--- jupyter: description: 'Section properties with planex2d: the centroid, second moment of area, section modulus and radius of gyration of shapes from the textbook list, the parallel axis theorem on an I-beam, an IPE 200 and an unequal angle against the steel tables, and the principal axes by Mohr''s circle.' --- # Section properties of steel profiles How stiff is a beam's cross-section? In bending, a beam's stiffness is $EI$, the material's modulus times the second moment of area of its section, $I = \int y^2\,dA$ about the axis through the section's centroid. Steel catalogs list $I$ for every rolled profile, with the elastic section modulus $W = I / y_{max}$, which gives the bending stress at the outer fiber, and the radius of gyration $i = \sqrt{I/A}$, which enters the buckling of columns. All of them follow from the profile's drawing alone. Here they are measured on the drawing and checked against the formulas and the catalogs. `face.Measure()` returns them in one dictionary, from the face's exact lines and arcs: | Key | Value | |---|---| | `"area"` | The area $A$ | | `"center"` | The centroid | | `"Ih"`, `"Iv"` | The second moments $I_h = \int v^2\,dA$ and $I_v = \int h^2\,dA$ about the horizontal and the vertical axis through the centroid | | `"Ihv"` | The product of inertia $I_{hv} = \int h v\,dA$ | | `"I1"`, `"I2"`, `"principal_angle"` | The principal moments, the largest and the smallest second moment about an axis through the centroid, and the angle of the axis of $I_1$ from $h$ in degrees | ![An IPE 200 and an unequal angle, each with its centroid and principal axes](../_static/gallery/section-properties.png){.result} ```python import math import matplotlib.pyplot as plt import numpy as np import planex as px ``` ```python nbsphinx="hidden" from docs_figures import FACE, INK, PLANEX, RED, Row ``` ## Shapes from the list The [list of second moments of area](https://en.wikipedia.org/wiki/List_of_second_moments_of_area) starts with the simple shapes. The example measures four of them about their centroids (Figure 1): - a rectangle of 40 × 60, with $I = bh^3/12$; - a tube of 60 outside and 50 inside, with $I = \pi (D^4 - d^4)/64$; - a half disc of radius 20, with $I = (\pi/8 - 8/(9\pi))\,r^4$ about its centroid, which lies $4r/(3\pi)$ above the diameter; - a right triangle of 30 × 45, with $I = bh^3/36$. ```python shapes = { "rectangle": (px.QuickSketch().RectangleC(40, 60).Face(), 40 * 60**3 / 12), "tube": (px.Circle((0, 0), 30).Face() - px.Circle((0, 0), 25).Face(), math.pi * (60**4 - 50**4) / 64), "half disc": (px.QuickSketch((-20, 0)).Line(40).Turn(90).Arc(20, 180).Face(), (math.pi / 8 - 8 / (9 * math.pi)) * 20**4), "triangle": (px.QuickSketch().Line(30).Line((0, 45)).Close().Face(), 30 * 45**3 / 36), } for name, (face, exact) in shapes.items(): print(name, "Ih", face.Measure()["Ih"], "exact", exact) print("half disc centroid", shapes["half disc"][0].Measure()["center"][1], "exact", 4 * 20 / (3 * math.pi)) ``` ```python nbsphinx="hide-input" Row(*[(face, name.capitalize(), {"marks": [face.Measure()["center"][:2]]}) for name, (face, _) in shapes.items()], caption="Four shapes from the list, their centroids marked") ``` ## The parallel axis theorem A built-up section adds the second moments of its parts, each moved to the common axis by the parallel axis theorem, $I = \sum_i (I_i + A_i d_i^2)$, with $d_i$ the distance of the part's centroid from the axis. The example is an IPE 200 without its root radii, a web of 5.6 × 200 and two flanges of 100 × 8.5, united into one face. The theorem takes the web between the flanges, 183 high, and the two flanges at $d = 100 - 8.5/2$ from the axis: ```python web = px.QuickSketch().RectangleC(5.6, 200).Face() flanges = [px.QuickSketch((0, s * (100 - 8.5 / 2))).RectangleC(100, 8.5).Face() for s in (-1, 1)] sharp = px.Unify([web, *flanges]).Face() d = 100 - 8.5 / 2 print("Ih", sharp.Measure()["Ih"], "theorem", 5.6 * 183**3 / 12 + 2 * (100 * 8.5**3 / 12 + 100 * 8.5 * d**2)) ``` ## An IPE 200 against the table A rolled IPE 200 has root radii of 12 between the web and the flanges. Filleted there, the section has the values of the producers' tables, for example [Stad's](https://www.stad.fr/en/sections-products-ranges-ipe). The tables' $y$ axis is the strong axis, horizontal here, so $I_y$ is `"Ih"` and $I_z$ is `"Iv"`. The section moduli divide by the distance of the outer fiber, 100 from the strong axis and 50 from the weak one (Figure 2): ```python ipe = sharp.Filleted([(s * 5.6 / 2, t * (100 - 8.5)) for s in (-1, 1) for t in (-1, 1)], 12) m = ipe.Measure() A = m["area"] print("A", round(A / 100, 2), "cm², table 28.48") print("Iy", round(m["Ih"] / 1e4, 1), "cm⁴, table 1943 | Wel,y", round(m["Ih"] / 100 / 1e3, 1), "cm³, table 194.3") print("iy", round(math.sqrt(m["Ih"] / A) / 10, 2), "cm, table 8.26") print("Iz", round(m["Iv"] / 1e4, 1), "cm⁴, table 142 | Wel,z", round(m["Iv"] / 50 / 1e3, 1), "cm³, table 28.5") print("iz", round(math.sqrt(m["Iv"] / A) / 10, 2), "cm, table 2.24") ``` ```python nbsphinx="hide-input" Row((sharp, "Without the root radii"), (ipe, "IPE 200, the centroid marked", {"marks": [m["center"][:2]]}), caption="The IPE 200 from three rectangles, then filleted") ``` ## The principal axes of an angle An unequal angle has no axis of symmetry, so its strong axis is tilted. The example is an L 150 × 100 × 10, the long leg upright, with a root radius of 12 inside the corner and toe radii of 6 at the ends of the legs. Drawn with the pen and filleted at its three corners, it has the values of the section table, here as [RoyMech lists them](https://roymech.org/Useful_Tables/Sections/U_AngleA_dim_prop.html). They are the second moments and the product of inertia about the centroid, and the principal moments $I_1$ and $I_2$, which the table calls $I_u$ and $I_v$, with $\tan\alpha$ of the axis of $I_1$ (Figure 3): ```python angle = px.QuickSketch().Line(100).Turn(90).Line(10).Turn(90).Line(90).Turn(-90).Line(140).Turn(90).Line(10).Close() profile = angle.Face().Filleted((10, 10), 12).Filleted([(100, 10), (10, 150)], 6) m = profile.Measure() print("A", round(m["area"] / 100, 2), "cm², table 24.2") print("centroid", [round(c / 10, 2) for c in m["center"][:2]], "cm, table 2.34 and 4.81") print("Ih", round(m["Ih"] / 1e4, 1), "| Iv", round(m["Iv"] / 1e4, 1), "| Ihv", round(m["Ihv"] / 1e4, 1), "cm⁴, table 553, 198, -192") print("I1", round(m["I1"] / 1e4, 1), "| I2", round(m["I2"] / 1e4, 1), "cm⁴, table 637, 114") print("tan α", round(math.tan(math.radians(m["principal_angle"])), 3), "table 0.438") ``` ```python nbsphinx="hide-input" center, turn = m["center"][:2], math.radians(m["principal_angle"]) axes = [px.Line((center[0] - 90 * math.cos(a), center[1] - 90 * math.sin(a)), (center[0] + 90 * math.cos(a), center[1] + 90 * math.sin(a))) for a in (turn, turn + math.pi / 2)] Row((px.Compound([profile, *axes]), "The principal axes through the centroid", {"marks": [center]}), caption="The unequal angle L 150 × 100 × 10") ``` The principal values follow from $I_h$, $I_v$ and $I_{hv}$ by Mohr's circle. It is centered at $(I_h + I_v)/2$ with the radius $\sqrt{((I_h - I_v)/2)^2 + I_{hv}^2}$, and the principal axis turns from $h$ by $\alpha$ with $\tan 2\alpha = -2 I_{hv} / (I_h - I_v)$: ```python c, R = (m["Ih"] + m["Iv"]) / 2, math.hypot((m["Ih"] - m["Iv"]) / 2, m["Ihv"]) print("I1", round((c + R) / 1e4, 1), "| I2", round((c - R) / 1e4, 1), "cm⁴") print("α", math.degrees(math.atan2(-2 * m["Ihv"], m["Ih"] - m["Iv"])) / 2, "measured", m["principal_angle"]) ``` The circle carries the two points $(I_h, I_{hv})$ and $(I_v, -I_{hv})$ in blue, and the principal moments, red, lie where it crosses the axis: ```python nbsphinx="hide-input" t = np.linspace(0, 2 * math.pi, 200) fig, ax = plt.subplots(figsize=(4.6, 3.4)) ax.plot((c + R * np.cos(t)) / 1e4, R * np.sin(t) / 1e4, color=INK, lw=1.6) ax.plot([m["Ih"] / 1e4, m["Iv"] / 1e4], [m["Ihv"] / 1e4, -m["Ihv"] / 1e4], "o-", color=PLANEX) ax.plot([(c - R) / 1e4, (c + R) / 1e4], [0, 0], "x", color=RED, markersize=9, mew=2) ax.set_aspect("equal") ax.set_xlabel("second moment in cm⁴", color=INK) ax.set_ylabel("product of inertia in cm⁴", color=INK) plt.show() ``` ```python nbsphinx="hidden" import sys sys.path.insert(0, "..") from gallery import save_figure shift = (110, -95) profiles = ((ipe, ipe.Measure()["center"][:2], 0.0, 120), (profile.Translated(shift), np.add(m["center"][:2], shift), math.radians(m["principal_angle"]), 95)) fig, ax = plt.subplots(figsize=(6, 4)) for face, center, turn, half in profiles: face.Plot(ax=ax, face_col="#c3cbd3", line_col=INK, arc_col=INK, spline_col=INK, legend=False) for a in (turn, turn + math.pi / 2): ax.plot([center[0] - half * math.cos(a), center[0] + half * math.cos(a)], [center[1] - half * math.sin(a), center[1] + half * math.sin(a)], color=RED, lw=1.3, dashes=(6, 3), zorder=5) ax.plot(*center, "x", color=RED, ms=8, mew=2, zorder=6) save_figure(fig, "section-properties", bare=True) ```