Beam Deflection | Strength of Materials with Python | Skill-Lync Resources

50% OFF - Ends Soon!

Lesson 6 of 13 30 min

Beam Deflection

Deflection limits often govern beam design more than stress. A beam might be strong enough but deflect too much, causing serviceability problems.

The Governing Equation

The relationship between bending moment and deflection:

$$EI\frac{d^2y}{dx^2} = M(x)$$

Sponsored

Ranjith switched from IT to core automotive industry

His inspiring career transition story with video

See His Journey

Or in terms of distributed load:

$$EI\frac{d^4y}{dx^4} = -w(x)$$

Where:

Sponsored

Srinithin now works at Xitadel as Design Engineer

Mechanical engineering graduate turned automotive designer

See His Journey
  • $y$ = Deflection
  • $E$ = Young's modulus
  • $I$ = Moment of inertia
  • $M(x)$ = Bending moment function
  • $w(x)$ = Distributed load (positive upward)

Standard Beam Deflection Formulas

import numpy as np
import matplotlib.pyplot as plt

class BeamDeflection:
    """Collection of standard beam deflection formulas."""

    @staticmethod
    def cantilever_point_load(P, L, E, I, x=None):
        """
        Cantilever beam with point load at free end.

        P = Load (N)
        L = Length (mm)
        E = Young's modulus (MPa)
        I = Moment of inertia (mm⁴)
        x = Position(s) from fixed end (mm), default is full length array
        """
        if x is None:
            x = np.linspace(0, L, 100)

        # Deflection formula: y = Px²(3L - x) / (6EI)
        y = P * x**2 * (3*L - x) / (6 * E * I)

        # Maximum deflection at free end
        y_max = P * L**3 / (3 * E * I)

        # Slope at free end
        theta_max = P * L**2 / (2 * E * I)

        return {
            'x': x,
            'y': y,
            'y_max': y_max,
            'theta_max_rad': theta_max,
            'type': 'Cantilever with point load at end'
        }

    @staticmethod
    def cantilever_udl(w, L, E, I, x=None):
        """
        Cantilever beam with uniformly distributed load.

        w = Load per unit length (N/mm)
        """
        if x is None:
            x = np.linspace(0, L, 100)

        # y = wx²(6L² - 4Lx + x²) / (24EI)
        y = w * x**2 * (6*L**2 - 4*L*x + x**2) / (24 * E * I)

        y_max = w * L**4 / (8 * E * I)
        theta_max = w * L**3 / (6 * E * I)

        return {
            'x': x,
            'y': y,
            'y_max': y_max,
            'theta_max_rad': theta_max,
            'type': 'Cantilever with UDL'
        }

    @staticmethod
    def simply_supported_center_load(P, L, E, I, x=None):
        """
        Simply supported beam with point load at center.
        """
        if x is None:
            x = np.linspace(0, L, 100)

        # Piecewise formula
        y = np.where(
            x <= L/2,
            P * x * (3*L**2 - 4*x**2) / (48 * E * I),
            P * (L - x) * (3*L**2 - 4*(L-x)**2) / (48 * E * I)
        )

        y_max = P * L**3 / (48 * E * I)

        return {
            'x': x,
            'y': y,
            'y_max': y_max,
            'type': 'Simply supported with center point load'
        }

    @staticmethod
    def simply_supported_udl(w, L, E, I, x=None):
        """
        Simply supported beam with uniformly distributed load.
        """
        if x is None:
            x = np.linspace(0, L, 100)

        # y = wx(L³ - 2Lx² + x³) / (24EI)
        y = w * x * (L**3 - 2*L*x**2 + x**3) / (24 * E * I)

        y_max = 5 * w * L**4 / (384 * E * I)

        return {
            'x': x,
            'y': y,
            'y_max': y_max,
            'type': 'Simply supported with UDL'
        }

    @staticmethod
    def fixed_fixed_center_load(P, L, E, I, x=None):
        """
        Fixed-fixed beam with point load at center.
        """
        if x is None:
            x = np.linspace(0, L, 100)

        # For center load
        y = np.where(
            x <= L/2,
            P * x**2 * (3*L - 4*x) / (48 * E * I),
            P * (L - x)**2 * (3*L - 4*(L-x)) / (48 * E * I)
        )

        y_max = P * L**3 / (192 * E * I)

        return {
            'x': x,
            'y': y,
            'y_max': y_max,
            'type': 'Fixed-fixed with center point load'
        }

    @staticmethod
    def fixed_fixed_udl(w, L, E, I, x=None):
        """
        Fixed-fixed beam with uniformly distributed load.
        """
        if x is None:
            x = np.linspace(0, L, 100)

        y = w * x**2 * (L - x)**2 / (24 * E * I)

        y_max = w * L**4 / (384 * E * I)

        return {
            'x': x,
            'y': y,
            'y_max': y_max,
            'type': 'Fixed-fixed with UDL'
        }


# Example usage
E = 200e3  # Steel, MPa
I = 8.33e6  # 100×200mm rectangle, mm⁴
L = 3000   # 3 meters
P = 10e3   # 10 kN

# Compare different support conditions
beam = BeamDeflection()

configs = [
    ('Cantilever', beam.cantilever_point_load(P, L, E, I)),
    ('Simply Supported', beam.simply_supported_center_load(P, L, E, I)),
    ('Fixed-Fixed', beam.fixed_fixed_center_load(P, L, E, I))
]

print("Beam Deflection Comparison")
print(f"Load: {P/1000:.1f} kN, Span: {L} mm")
print(f"E = {E/1000:.0f} GPa, I = {I:.2e} mm⁴")
print("-" * 50)

for name, result in configs:
    print(f"{name}: δmax = {result['y_max']:.3f} mm")
🎯 3,000+ Engineers Placed
Sponsored
Harshal Sukenkar

Harshal

Fiat Chrysler

Abhishek

Abhishek

TATA ELXSI

Srinithin

Srinithin

Xitadel

Ranjith

Ranjith

Core Automotive

Gaurav Jadhav

Gaurav

Automotive Company

Bino K Biju

Bino

Design Firm

Aseem Shrivastava

Aseem

EV Company

Puneet

Puneet

Automotive Company

Vishal Kumar

Vishal

EV Startup

Visualizing Deflection Curves

def plot_deflection_comparison():
    """Compare deflection curves for different support conditions."""

    E = 200e3  # MPa
    I = 5e6    # mm⁴
    L = 2000   # mm
    P = 5e3    # N

    beam = BeamDeflection()

    fig, axes = plt.subplots(2, 2, figsize=(14, 10))

    # 1. Cantilever with point load
    ax1 = axes[0, 0]
    result = beam.cantilever_point_load(P, L, E, I)
    ax1.fill_between(result['x'], 0, -result['y'], alpha=0.3, color='blue')
    ax1.plot(result['x'], -result['y'], 'b-', lw=2)
    ax1.axhline(y=0, color='k', lw=1)
    # Fixed support
    ax1.fill_between([-50, 0], [-5, -5], [5, 5], color='gray', alpha=0.5)
    # Load arrow
    ax1.annotate('', xy=(L, -result['y_max']), xytext=(L, -result['y_max']-100),
                arrowprops=dict(arrowstyle='->', lw=2, color='red'))
    ax1.text(L, -result['y_max']-120, f'P={P/1000:.0f}kN', ha='center', color='red')
    ax1.set_title(f"Cantilever: δmax = {result['y_max']:.2f} mm")
    ax1.set_xlabel('x (mm)')
    ax1.set_ylabel('Deflection (mm)')
    ax1.grid(True, alpha=0.3)
    ax1.set_xlim(-100, L+100)

    # 2. Simply supported with center load
    ax2 = axes[0, 1]
    result = beam.simply_supported_center_load(P, L, E, I)
    ax2.fill_between(result['x'], 0, -result['y'], alpha=0.3, color='green')
    ax2.plot(result['x'], -result['y'], 'g-', lw=2)
    ax2.axhline(y=0, color='k', lw=1)
    # Supports
    ax2.scatter([0, L], [0, 0], s=300, marker='^', color='gray', zorder=5)
    # Load
    ax2.annotate('', xy=(L/2, -result['y_max']), xytext=(L/2, -result['y_max']-100),
                arrowprops=dict(arrowstyle='->', lw=2, color='red'))
    ax2.set_title(f"Simply Supported: δmax = {result['y_max']:.2f} mm")
    ax2.set_xlabel('x (mm)')
    ax2.set_ylabel('Deflection (mm)')
    ax2.grid(True, alpha=0.3)

    # 3. Fixed-fixed with center load
    ax3 = axes[1, 0]
    result = beam.fixed_fixed_center_load(P, L, E, I)
    ax3.fill_between(result['x'], 0, -result['y'], alpha=0.3, color='orange')
    ax3.plot(result['x'], -result['y'], 'orange', lw=2)
    ax3.axhline(y=0, color='k', lw=1)
    # Fixed supports
    ax3.fill_between([-50, 0], [-5, -5], [5, 5], color='gray', alpha=0.5)
    ax3.fill_between([L, L+50], [-5, -5], [5, 5], color='gray', alpha=0.5)
    ax3.set_title(f"Fixed-Fixed: δmax = {result['y_max']:.2f} mm")
    ax3.set_xlabel('x (mm)')
    ax3.set_ylabel('Deflection (mm)')
    ax3.grid(True, alpha=0.3)
    ax3.set_xlim(-100, L+100)

    # 4. Comparison
    ax4 = axes[1, 1]

    for name, color, func in [
        ('Cantilever', 'blue', beam.cantilever_point_load),
        ('Simply Supported', 'green', beam.simply_supported_center_load),
        ('Fixed-Fixed', 'orange', beam.fixed_fixed_center_load)
    ]:
        result = func(P, L, E, I)
        # Normalize to compare shapes
        y_norm = result['y'] / result['y_max']
        ax4.plot(result['x']/L, y_norm, lw=2, label=name)

    ax4.set_xlabel('Normalized Position (x/L)')
    ax4.set_ylabel('Normalized Deflection (y/ymax)')
    ax4.set_title('Shape Comparison (Normalized)')
    ax4.legend()
    ax4.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

plot_deflection_comparison()

Superposition Method

For beams with multiple loads, we can add individual deflections:

$$\delta_{total} = \delta_1 + \delta_2 + \delta_3 + ...$$

def superposition_example():
    """
    Example: Simply supported beam with multiple loads.

    |----a----|
    P1        P2        w (UDL)
    ↓         ↓         ↓↓↓↓↓↓
    ================
    △                   △
    |--------L---------|
    """
    E = 200e3  # MPa
    I = 10e6   # mm⁴
    L = 4000   # mm

    # Loads
    P1 = 8e3   # N at x = 1000mm
    P2 = 5e3   # N at x = 2500mm
    w = 5      # N/mm (UDL over entire span)

    x = np.linspace(0, L, 200)

    # Individual deflections
    beam = BeamDeflection()

    # UDL deflection
    y_udl = beam.simply_supported_udl(w, L, E, I, x)['y']

    # Point loads (use general formula for load at distance 'a' from left)
    def point_load_deflection(P, a, L, E, I, x):
        """Deflection for point load P at distance a from left support."""
        b = L - a
        y = np.zeros_like(x)

        # For x <= a
        mask1 = x <= a
        y[mask1] = P * b * x[mask1] / (6 * L * E * I) * \
                   (L**2 - b**2 - x[mask1]**2)

        # For x > a
        mask2 = x > a
        y[mask2] = P * b / (6 * L * E * I) * \
                   (L/b * (x[mask2] - a)**3 + (L**2 - b**2)*x[mask2] - x[mask2]**3)

        return y

    y_P1 = point_load_deflection(P1, 1000, L, E, I, x)
    y_P2 = point_load_deflection(P2, 2500, L, E, I, x)

    # Total deflection
    y_total = y_udl + y_P1 + y_P2

    # Plot
    fig, axes = plt.subplots(2, 1, figsize=(12, 8))

    # Individual components
    ax1 = axes[0]
    ax1.plot(x, -y_udl, 'b--', lw=1.5, label=f'UDL (w={w} N/mm)')
    ax1.plot(x, -y_P1, 'g--', lw=1.5, label=f'P1={P1/1000}kN at 1000mm')
    ax1.plot(x, -y_P2, 'r--', lw=1.5, label=f'P2={P2/1000}kN at 2500mm')
    ax1.axhline(y=0, color='k', lw=0.5)
    ax1.set_xlabel('x (mm)')
    ax1.set_ylabel('Deflection (mm)')
    ax1.set_title('Individual Load Contributions')
    ax1.legend()
    ax1.grid(True, alpha=0.3)

    # Total
    ax2 = axes[1]
    ax2.fill_between(x, 0, -y_total, alpha=0.3, color='purple')
    ax2.plot(x, -y_total, 'purple', lw=2, label='Total deflection')
    ax2.axhline(y=0, color='k', lw=0.5)

    # Mark maximum
    idx_max = np.argmax(y_total)
    ax2.scatter([x[idx_max]], [-y_total[idx_max]], s=100, color='red', zorder=5)
    ax2.annotate(f'δmax = {y_total[idx_max]:.2f} mm\nat x = {x[idx_max]:.0f} mm',
                xy=(x[idx_max], -y_total[idx_max]),
                xytext=(x[idx_max]+200, -y_total[idx_max]-1),
                fontsize=10, color='red')

    ax2.set_xlabel('x (mm)')
    ax2.set_ylabel('Deflection (mm)')
    ax2.set_title('Total Deflection (Superposition)')
    ax2.legend()
    ax2.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

    print(f"Maximum deflection: {max(y_total):.3f} mm")
    print(f"Location: {x[np.argmax(y_total)]:.0f} mm from left support")

superposition_example()

Deflection Limits

Common serviceability limits:

Sponsored

Gaurav Jadhav is now a CAE Engineer

Practical projects and mock interviews made the difference

See His Journey
ApplicationDeflection Limit
Floor beamsL/360
Roof beamsL/240
CantileversL/180
Industrial buildingsL/200
def check_deflection_limits(L_mm, delta_max_mm, application='floor'):
    """Check if deflection meets serviceability limits."""

    limits = {
        'floor': 360,
        'roof': 240,
        'cantilever': 180,
        'industrial': 200
    }

    limit_ratio = limits.get(application, 360)
    allowable = L_mm / limit_ratio
    actual_ratio = L_mm / delta_max_mm if delta_max_mm > 0 else float('inf')

    print(f"Deflection Check ({application}):")
    print(f"  Span: {L_mm} mm")
    print(f"  Maximum deflection: {delta_max_mm:.2f} mm")
    print(f"  Allowable (L/{limit_ratio}): {allowable:.2f} mm")
    print(f"  Actual ratio: L/{actual_ratio:.0f}")
    print(f"  Status: {'PASS ✓' if delta_max_mm <= allowable else 'FAIL ✗'}")

    return delta_max_mm <= allowable

# Example
check_deflection_limits(L_mm=6000, delta_max_mm=20, application='floor')

Moment-Area Method

An alternative to integration, useful for complex loading:

First Moment-Area Theorem:

The angle between tangents at two points equals the area under the M/EI diagram.

Second Moment-Area Theorem:

The vertical distance from a point to the tangent drawn from another point equals the first moment of the M/EI area about the point.

def moment_area_cantilever(P, L, E, I):
    """
    Use moment-area method for cantilever with end load.
    """
    # M/EI diagram is triangular: M = -P(L-x) for cantilever
    # At fixed end: M = -PL
    # At free end: M = 0

    # Area under M/EI diagram
    area = 0.5 * L * (P * L) / (E * I)

    # Centroid of triangle from free end
    x_bar = L / 3

    # Deflection at free end = moment of area about free end
    delta = area * (L - L/3)  # First moment about free end

    # Actually, for cantilever it's simpler:
    # Tangent at fixed end is horizontal
    # Deflection at free end = first moment of M/EI about free end

    delta_correct = (1/2 * L * P*L/(E*I)) * (2*L/3)  # = PL³/3EI

    print(f"Moment-Area Method - Cantilever")
    print(f"  Standard formula: δ = PL³/(3EI) = {P*L**3/(3*E*I):.3f} mm")
    print(f"  Moment-area result: {delta_correct:.3f} mm")

moment_area_cantilever(P=10e3, L=2000, E=200e3, I=5e6)

Key Takeaways

  • Governing equation: $EI \cdot d²y/dx² = M(x)$
  • Stiffer beams (higher EI) deflect less
  • Fixed supports reduce deflection compared to simple supports
  • Superposition: Add deflections from individual loads
  • Deflection limits: Typically L/360 for floors, L/240 for roofs

Next lesson: We'll learn to generate shear force and bending moment diagrams automatically.

3,000+ Engineers Placed in Top Companies
Career Growth

3,000+ Engineers Placed in Top Companies

Join the ranks of successful engineers at Bosch, Tata, L&T, and 500+ hiring partners.

Beam Bending Theory