Code

Validate a beam deflection formula against a cited reference

Implement the simply-supported uniform-load Euler–Bernoulli midspan deflection, check it with scaling identities, and refuse to treat an uncited coefficient as engineering output.

A beam formula in a script is only as good as the reference behind the coefficient. This tutorial implements one elementary result — midspan deflection of a prismatic, simply supported Euler–Bernoulli beam under uniform load — cites a textbook class of sources, and checks the implementation with identities that do not require copying tables from a building code.

The goal is a verification habit: formula, citation, unit system, independent check. It is not a design of a member, not a code check, and not a substitute for OpenSees or a licensed analysis.

The cited result

For a simply supported span LL, constant EIEI, uniform load ww per unit length, small deflections, Euler–Bernoulli kinematics (plane sections remain plane, no shear deformation), the midspan transverse deflection magnitude is:

δ=5wL4384EI\delta = \frac{5 w L^{4}}{384 E I}
Check path: cited formula, coherent units, then scaling identities
Diagram source
flowchart LR
  cite[Cited formula] --> units[Coherent SI units]
  units --> run[Run script]
  run --> scale[Scaling identities]
  scale --> keep[Keep the coefficient]

That expression is standard in elementary strength of materials. Cite the edition on your shelf, for example Timoshenko and Gere, Mechanics of Materials, in the chapter on deflection of beams. Do not paste scanned textbook pages or copyrighted commentary. Do not replace this citation with an AISC, Eurocode, or NSR table excerpt.

A different problem — midspan point load PP on the same beam — has δ=PL3/(48EI)\delta = P L^{3} / (48 E I). Mixing 5/3845/384 with a point load (or 1/481/48 with a uniform load) is a common silent error. The script below takes w and refuses a P argument so the two cases cannot be collapsed by accident.

Prerequisites

  • Python 3 (stdlib only)
  • Clear SI units: w in N/m, L in m, E in Pa, I in m⁴, δ in m
  • The units tutorial if you are tempted to mix mm and m

Implementation

from __future__ import annotations


def midspan_uniform_ss(w: float, L: float, E: float, I: float) -> float:
    """Euler–Bernoulli midspan |δ| for simple supports and uniform w.

    Referee: Timoshenko & Gere, Mechanics of Materials (elementary beam
    deflection). Not a building-code clause.
    """
    if min(w, L, E, I) <= 0.0:
        raise ValueError("w, L, E, I must be positive")
    return 5.0 * w * L**4 / (384.0 * E * I)


def scaling_checks(w: float, L: float, E: float, I: float, atol_rel: float = 1e-12) -> None:
    d = midspan_uniform_ss(w, L, E, I)
    d_ei = midspan_uniform_ss(w, L, 2.0 * E, I)
    d_l = midspan_uniform_ss(w, 2.0 * L, E, I)
    d_w = midspan_uniform_ss(2.0 * w, L, E, I)

    def rel(a: float, b: float) -> float:
        return abs(a - b) / abs(b)

    if rel(d_ei, d / 2.0) > atol_rel:
        raise SystemExit("doubling EI must halve δ")
    if rel(d_w, 2.0 * d) > atol_rel:
        raise SystemExit("doubling w must double δ")
    if rel(d_l, 16.0 * d) > atol_rel:
        raise SystemExit("doubling L must multiply δ by 16 (L^4)")


if __name__ == "__main__":
    # Documented SI example — not a designed section.
    w = 10_000.0    # N/m
    L = 6.0         # m
    E = 2.0e11      # Pa
    I = 8.0e-5      # m⁴
    delta_m = midspan_uniform_ss(w, L, E, I)
    scaling_checks(w, L, E, I)
    print(f"δ = {delta_m:.6e} m  ({delta_m * 1e3:.3f} mm)")
    print("scaling identities passed")

The printout for this particular tuple is on the order of 10 mm. If you see metres or nanometres, the unit set is wrong. That order-of-magnitude statement is a sanity bound, not a pass/fail against a code deflection limit.

Independent numerical check

The companion OpenSees tutorial (opensees-first-elastic-model) is a cantilever with a tip load. That closed form is P L³ / (3 E I), not 5 w L⁴ / (384 E I). To check this formula in a solver you must model simple supports and a uniform load, then compare midspan uy to midspan_uniform_ss. Do not claim the cantilever tutorial already verified this case.

If you do build that OpenSees model, keep Linear geometry, a prismatic elasticBeamColumn (several segments if you apply equivalent nodal loads, or an element load if your build supports -beamUniform), pins that restrain the correct DOFs, and the same SI unit set. One cubic element with only end nodes cannot represent a true uniform load unless the load is applied as an element load the formulation supports.

Validation

  1. Citation. The coefficient 5/384 is written next to Timoshenko & Gere (or another strength-of-materials text you actually own). An uncited fraction from a chat window is not validated.
  2. Scaling identities. δ scales with w, with 1/EI, and with L⁴. These follow from the same Euler–Bernoulli equation; if they fail, the implementation is wrong even if a single numerical example “looks reasonable.”
  3. Wrong-formula trap. Evaluating P L³ / (48 E I) with P = w L does not recover 5 w L⁴ / (384 E I). w L as a single midspan force is a different load path. Keep a test that asserts the two expressions differ.
  4. Units. Repeat the evaluation in N-mm and convert δ to mm; the SI and N-mm results must agree (see unit-conversion-pitfalls-civil-scripts).
  5. Sign. The formula above is a magnitude. A solver DOF may be negative. Compare absolute values only after you have checked the load direction.

Common mistakes

  • Using 5/384 for a cantilever, or P L³ / (3 E I) for simple supports.
  • Taking I from a catalogue in mm⁴ and L in metres.
  • Applying load factors or φ/Ω factors inside the “formula check.” Verification of the algebra comes first; reliability factors are a different layer.
  • Letting an assistant rewrite the coefficient “for I-beams” or “for concrete.” The Euler–Bernoulli result above is not section-type-specific; it is kinematic and constitutive under the stated assumptions.

Limitations

  • No shear deformation (Timoshenko beam), no warping, no torsion, no cracking, no composite action.
  • Prismatic, statically determinate, uniform w, linear elastic, small slopes.
  • Supports are ideal pins. Settlement, spring supports, and continuity over multiple spans need different solutions (moment distribution, slope-deflection, or a solver).
  • Not a serviceability check against a code deflection cap. Those caps, load combinations, and live-load patterns live in the governing standard — cite the standard by designation and clause without quoting copyrighted text.
  • Dynamics (mass, period, spectra) are outside this page. Chopra, Dynamics of Structures (content id chopra-dynamics-of-structures), is the usual next theoretical step; it does not replace this static identity.

Professional context

Engineers sign models, not chat completions. A formula helper belongs in a repository with the citation in the docstring, the scaling tests in CI, and a note that production members need the project’s analysis method and the code in force. If you cannot name the reference for 5/384, do not ship the function.

References

  • Timoshenko, S. P., and Gere, J. M. Mechanics of Materials. Simply supported beam, uniform load, midspan deflection 5 w L⁴ / (384 E I). Use the edition you have; do not reproduce long extracts.
  • Hibbeler, R. C. Structural Analysis or Mechanics of Materials — equivalent elementary tables in many editions; still cite rather than copy.
  • OpenSeesPy documentation, for an independent numerical model of a different boundary-value problem unless you rebuild simple supports and uniform load on purpose.