BEAM_2D

This function performs two-dimensional beam analysis by constructing a finite element model from span geometry, support conditions, material/section properties, and applied loads. It supports common beam loading types such as concentrated forces and distributed loads, then solves for nodal reactions, displacements, internal shear/moment response, and deflection summaries.

The underlying beam equilibrium is governed by force and moment balance, with stiffness-based solution of nodal unknowns. For a linear static case, the assembled system is solved as:

\mathbf{K}\mathbf{u} = \mathbf{F}

where \mathbf{K} is the global stiffness matrix, \mathbf{u} is the nodal displacement vector, and \mathbf{F} is the applied load vector. Member result quantities are then recovered from the solved displacement state.

Excel Usage

=BEAM_2D(spans, supports, loads, material_section, pynite_beam_output)
  • spans (list[list], required): List of span lengths [length].
  • supports (list[list], required): Support locations and types [x_location, type]. Type=‘pinned’, ‘fixed’, ‘roller’, ‘free’.
  • loads (list[list], required): Loads [type, magnitude, x_start, x_end]. Type=‘point’, ‘distributed’, ‘moment’.
  • material_section (list[list], required): Material and Section properties [E, G, nu, rho, A, Iy].
  • pynite_beam_output (str, optional, default: “Reactions”): Output type.

Returns (list[list]): Analysis results based on pynite_output.

Example 1: Simply supported beam reactions under uniform load

Inputs:

spans supports loads material_section pynite_beam_output
10 0 pinned dist -1 0 10 29000 11200 0.3 0 10 100 Reactions
10 roller

Excel formula:

=BEAM_2D({10}, {0,"pinned";10,"roller"}, {"dist",-1,0,10}, {29000,11200,0.3,0,10,100}, "Reactions")

Expected output:

Node Rx (k) Ry (k) Mz (k-ft)
N0 0 5 0
N1 0 5 0
Example 2: Cantilever beam tip displacement under end point load

Inputs:

spans supports loads material_section pynite_beam_output
10 0 fixed point -1 10 29000 11200 0.3 0 10 100 Displacements

Excel formula:

=BEAM_2D({10}, {0,"fixed"}, {"point",-1,10}, {29000,11200,0.3,0,10,100}, "Displacements")

Expected output:

Node Dx (in) Dy (in) Rz (rad)
N0 0 0 0
N1 0 -0.0114943 -0.00172414
Example 3: Shear diagram samples for uniformly loaded simple span

Inputs:

spans supports loads material_section pynite_beam_output
10 0 pinned dist -1 0 10 29000 11200 0.3 0 10 100 Shear
10 roller

Excel formula:

=BEAM_2D({10}, {0,"pinned";10,"roller"}, {"dist",-1,0,10}, {29000,11200,0.3,0,10,100}, "Shear")

Expected output:

Member Loc (ft) Shear (k)
M1 0 5
M1 5 0
M1 10 -5
Example 4: Moment diagram samples for uniformly loaded simple span

Inputs:

spans supports loads material_section pynite_beam_output
10 0 pinned dist -1 0 10 29000 11200 0.3 0 10 100 Moment
10 roller

Excel formula:

=BEAM_2D({10}, {0,"pinned";10,"roller"}, {"dist",-1,0,10}, {29000,11200,0.3,0,10,100}, "Moment")

Expected output:

Member Loc (ft) Moment (k-ft)
M1 0 0
M1 5 -12.5
M1 10 0
Example 5: Support-node deflection summary for a centered point load

Inputs:

spans supports loads material_section pynite_beam_output
10 0 pinned point -1 5 29000 11200 0.3 0 10 100 Deflection
10 roller

Excel formula:

=BEAM_2D({10}, {0,"pinned";10,"roller"}, {"point",-1,5}, {29000,11200,0.3,0,10,100}, "Deflection")

Expected output:

Node Dy (in)
N0 0
N1 0
Example 6: Combined beam output for a uniformly loaded simple span

Inputs:

spans supports loads material_section pynite_beam_output
10 0 pinned dist -1 0 10 29000 11200 0.3 0 10 100 Stacked
10 roller

Excel formula:

=BEAM_2D({10}, {0,"pinned";10,"roller"}, {"dist",-1,0,10}, {29000,11200,0.3,0,10,100}, "Stacked")

Expected output:

Node Rx (k) Ry (k) Mz (k-ft)
N0 0 5 0
N1 0 5 0
Node Dx (in) Dy (in) Rz (rad)
N0 0 0 -0.00143678
N1 0 0 0.00143678
Member Loc (ft) Shear (k)
M1 0 5
M1 5 0
M1 10 -5
Member Loc (ft) Moment (k-ft)
M1 0 0
M1 5 -12.5
M1 10 0
Node Dy (in)
N0 0
N1 0

Python Code

Show Code
from Pynite import FEModel3D

def beam_2d(spans, supports, loads, material_section, pynite_beam_output='Reactions'):
    """
    Analyze continuous 2D beams with auto-meshing. Supports point and distributed loads.

    See: https://pynite.readthedocs.io/en/latest/member.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        spans (list[list]): List of span lengths [length].
        supports (list[list]): Support locations and types [x_location, type]. Type='pinned', 'fixed', 'roller', 'free'.
        loads (list[list]): Loads [type, magnitude, x_start, x_end]. Type='point', 'distributed', 'moment'.
        material_section (list[list]): Material and Section properties [E, G, nu, rho, A, Iy].
        pynite_beam_output (str, optional): Output type. Valid options: Reactions, Displacements, Shear Diagram, Moment Diagram, Deflection Plot, Stacked Results. Default is 'Reactions'.

    Returns:
        list[list]: Analysis results based on pynite_output.
    """
    try:
        # Helpers
        def to2d(x):
            return [[x]] if not isinstance(x, list) else x

        # Prepare inputs
        spans = [float(row[0]) for row in to2d(spans) if row[0] is not None]

        # Create Model
        model = FEModel3D()

        # Material/Section (Simplified: Uniform for now, or take first row)
        props = to2d(material_section)[0]
        E, G, nu, rho = float(props[0]), float(props[1]), float(props[2]), float(props[3])
        A, Iy = float(props[4]), float(props[5])

        model.add_material('Mat1', E, G, nu, rho)
        model.add_section('Sec1', A, Iy, 1.0, 1.0) # Dummy J, Iz for 2D beam

        # Generate Nodes and Members from Spans
        x_accum = 0.0
        node_names = ['N0']
        model.add_node('N0', 0, 0, 0)

        for i, length in enumerate(spans):
            x_end = x_accum + length
            n_name = f'N{i+1}'
            model.add_node(n_name, x_end, 0, 0)
            model.add_member(f'M{i+1}', node_names[-1], n_name, 'Mat1', 'Sec1')
            node_names.append(n_name)
            x_accum = x_end

        # 2D Stability: Fix all nodes out-of-plane
        for n_name in model.nodes:
            model.def_support(n_name, False, False, True, True, True, False)

        # Supports
        for row in to2d(supports):
            if not row or row[0] is None: continue
            x_loc = float(row[0])
            sup_type = str(row[1]).lower()
            for n_name in model.nodes:
                n = model.nodes[n_name]
                if abs(n.X - x_loc) < 1e-4:
                    if 'fixed' in sup_type:
                        model.def_support(n_name, True, True, True, True, True, True)
                    elif 'pinned' in sup_type:
                        model.def_support(n_name, True, True, True, True, True, False)
                    elif 'roller' in sup_type:
                        model.def_support(n_name, False, True, True, True, True, False)
                    break

        # Loads
        for row in to2d(loads):
            if not row or row[0] is None: continue
            l_type, mag, x1 = str(row[0]).lower(), float(row[1]), float(row[2])
            if 'point' in l_type:
                for m_name in model.members:
                    m = model.members[m_name]
                    if m.i_node.X <= x1 <= m.j_node.X:
                        model.add_member_pt_load(m_name, 'Fy', mag, x1 - m.i_node.X)
                        break
            elif 'dist' in l_type:
                x2 = float(row[3])
                for m_name in model.members:
                    m = model.members[m_name]
                    s, e = max(x1, m.i_node.X), min(x2, m.j_node.X)
                    if s < e:
                        model.add_member_dist_load(m_name, 'Fy', mag, mag, s - m.i_node.X, e - m.i_node.X)
            elif 'moment' in l_type:
              for m_name in model.members:
                m = model.members[m_name]
                if m.i_node.X <= x1 <= m.j_node.X:
                  model.add_member_pt_load(m_name, 'Mz', mag, x1 - m.i_node.X)
                  break

        # Safe result helper
        def get_val(obj, attr, *args):
            try:
                val = getattr(obj, attr)
                if callable(val): val = val(*args)
                if isinstance(val, dict): return float(val.get('Combo 1', 0.0))
                return float(val)
            except: return 0.0

        # Add load combination and analyze
        model.add_load_combo('Combo 1', {'Case 1': 1.0})
        model.analyze(check_statics=False)

        res = []
        # Column count for Stacked output: 4

        if pynite_beam_output == 'Reactions' or pynite_beam_output == 'Stacked':
            res.append(['Node', 'Rx (k)', 'Ry (k)', 'Mz (k-ft)'])
            for n_nm in model.nodes:
                n = model.nodes[n_nm]
                res.append([n_nm, get_val(n, 'RxnFX'), get_val(n, 'RxnFY'), get_val(n, 'RxnMZ')])

        if pynite_beam_output == 'Displacements' or pynite_beam_output == 'Stacked':
            res.append(['Node', 'Dx (in)', 'Dy (in)', 'Rz (rad)'])
            for n_nm in model.nodes:
                n = model.nodes[n_nm]
                res.append([n_nm, get_val(n, 'DX'), get_val(n, 'DY'), get_val(n, 'RZ')])

        if pynite_beam_output == 'Shear' or pynite_beam_output == 'Stacked':
            res.append(['Member', 'Loc (ft)', 'Shear (k)', ''])
            for m_nm in model.members:
                 m = model.members[m_nm]
                 for x in [0.0, m.L()/2, m.L()]:
                      res.append([m_nm, x, get_val(m, 'shear', 'Fy', x), ''])

        if pynite_beam_output == 'Moment' or pynite_beam_output == 'Stacked':
            res.append(['Member', 'Loc (ft)', 'Moment (k-ft)', ''])
            for m_nm in model.members:
                 m = model.members[m_nm]
                 for x in [0.0, m.L()/2, m.L()]:
                      res.append([m_nm, x, get_val(m, 'moment', 'Mz', x), ''])

        if pynite_beam_output == 'Deflection' or pynite_beam_output == 'Stacked':
            res.append(['Node', 'Dy (in)', '', ''])
            for n_nm in model.nodes:
                 res.append([n_nm, get_val(model.nodes[n_nm], 'DY'), '', ''])

        return res
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

List of span lengths [length].
Support locations and types [x_location, type]. Type='pinned', 'fixed', 'roller', 'free'.
Loads [type, magnitude, x_start, x_end]. Type='point', 'distributed', 'moment'.
Material and Section properties [E, G, nu, rho, A, Iy].
Output type.