codexfour-point-bending-moment-and-strain.py
four-point-bending-moment-and-strain.py
"""Original symmetric four-point loading and its elementary beam response."""
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def main():
span, offset, load = .160, .040, 40.0
width, height, young = .010, .004, 70e9
inertia = width * height**3 / 12
moment = load * offset / 2
curvature = moment / (young * inertia)
assert np.isclose(moment, .8)
assert np.isclose(moment * height / (2*inertia), 30e6)
assert np.isclose(curvature * height / 2, 3e-4 / .7)
fig = plt.figure(figsize=(10, 4.6), dpi=100, layout="constrained")
fig.set_facecolor("white")
grid = fig.add_gridspec(2, 2, width_ratios=[1.4, 1], height_ratios=[1, 1])
fixture = fig.add_subplot(grid[0, 0])
bending = fig.add_subplot(grid[1, 0])
strain = fig.add_subplot(grid[:, 1])
fixture.plot([0, 160], [0, 0], color="#555555", linewidth=5)
for x in [0, 160]:
fixture.scatter(x, -1.1, marker="^", color="#555555", s=90)
fixture.annotate("", (x, -.8), (x, -3.6),
arrowprops=dict(arrowstyle="->", color="#1565c0", lw=2))
fixture.text(x, -4.3, "20 N", ha="center", color="#1565c0")
for x in [40, 120]:
fixture.annotate("", (x, .4), (x, 4),
arrowprops=dict(arrowstyle="->", color="#b44e17", lw=2))
fixture.text(x, 4.3, "20 N", ha="center", color="#b44e17")
fixture.set(xlim=(-15, 175), ylim=(-6.3, 6), xticks=[0, 40, 120, 160],
yticks=[], title="Four-point fixture: total load 40 N")
fixture.set_xlabel("Position along beam (mm)")
for side in ["top", "right", "left"]:
fixture.spines[side].set_visible(False)
x = np.linspace(0, span, 501)
m = np.minimum(np.minimum(x, span-x), offset) * load/2
assert np.allclose(m[(x > offset) & (x < span-offset)], moment)
bending.plot(x*1e3, m, color="#1565c0", lw=2)
bending.fill_between(x*1e3, 0, m, color="#1565c0", alpha=.12)
bending.axvspan(40, 120, color="#d5e8ce", alpha=.4)
bending.text(80, .43, "Pure bending\nV = 0", ha="center")
bending.set(xlabel="Position along beam (mm)", ylabel="Moment (N m)",
ylim=(0, 1), xlim=(0, 160), title="Constant central moment: 0.800 N m")
bending.grid(alpha=.18)
y = np.linspace(-height/2, height/2, 101)
epsilon = -curvature*y
strain.plot(epsilon*1e6, y*1e3, color="#b44e17", lw=2)
strain.axhline(0, color="#777777", ls="--", lw=1)
strain.axvline(0, color="#bbbbbb", lw=1)
strain.text(0, .15, "Neutral axis", ha="center", fontsize=10)
strain.scatter(epsilon[[0, -1]]*1e6, y[[0, -1]]*1e3, color="#b44e17")
strain.set(xlabel="Longitudinal strain (microstrain)",
ylabel="Height y from neutral axis (mm)",
title="Central-section strain\nE = 70 GPa; b = 10 mm; h = 4 mm",
xlim=(-550, 550), ylim=(-2.5, 2.5))
strain.grid(alpha=.18)
fig.savefig(Path(__file__).with_suffix(".png").name, facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()