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)}"