Cantilever tip deflection — Euler-Bernoulli closed form#

Slender clamped cantilever under a transverse tip load has tip deflection

\[\delta = \frac{P L^{3}}{3 E I}, \qquad I = \frac{w h^{3}}{12}.\]

Reference: Timoshenko, S. P. Strength of Materials, Part I, 3rd ed., Van Nostrand, 1955, §5.4.

This gallery example drives a multi-refinement ConvergenceStudy and renders the deformed shape at the finest mesh.

from __future__ import annotations

import numpy as np
import pyvista as pv

from femorph_solver.validation import ConvergenceStudy
from femorph_solver.validation.problems import CantileverEulerBernoulli

Problem + convergence ladder#

Three in-plane refinements (slenderness L/h = 20); three transverse layers keeps the shear-strain field resolved at the HEX8 EAS formulation used under the hood.

problem = CantileverEulerBernoulli()
study = ConvergenceStudy(
    problem=problem,
    refinements=[
        {"nx": 20, "ny": 3, "nz": 3},
        {"nx": 40, "ny": 3, "nz": 3},
        {"nx": 80, "ny": 3, "nz": 3},
    ],
)
records = study.run()

Print the comparison table

rec = records[0]
pub = rec.results[0].published
print(f"{problem.name}: {problem.description}")
print(f"\n  source : {pub.source}")
print(f"  formula: {pub.formula}")
print(f"  published: {pub.value:.6e} {pub.unit}\n")
print(f"  {'mesh':<20s} {'n_dof':>8s} {'computed':>14s} {'rel err':>10s}  pass")
for r in rec.results:
    mesh_str = "  ".join(f"{k}={v}" for k, v in r.mesh_params.items())
    pass_str = "✓" if r.passed else "✗"
    print(
        f"  {mesh_str:<20s} {r.n_dof:>8d} {r.computed:+14.6e} "
        f"{r.rel_error * 100:+9.2f}%   {pass_str}"
    )
if rec.convergence_rate is not None:
    print(f"\n  fitted rate: |err| ∝ n_dof^(-{rec.convergence_rate:.2f})")
cantilever_eb: Slender clamped cantilever under transverse tip load — Euler-Bernoulli closed-form (Timoshenko 1955 §5.4).

  source : Timoshenko 1955 §5.4
  formula: delta = P L^3 / (3 E I)
  published: 3.200000e-03 m

  mesh                    n_dof       computed    rel err  pass
  nx=20  ny=3  nz=3        1008  +3.168413e-03     -0.99%   ✓
  nx=40  ny=3  nz=3        1968  +3.184714e-03     -0.48%   ✓
  nx=80  ny=3  nz=3        3888  +3.191451e-03     -0.27%   ✓

  fitted rate: |err| ∝ n_dof^(-0.85)

Render the deformed shape at the finest mesh#

m = problem.build_model(nx=80, ny=3, nz=3)
res = m.solve()
u = np.asarray(res.displacement).reshape(-1, 3)

warped = m.grid.copy()
warped.points = m.grid.points + 1.0 * u
warped["|u|"] = np.linalg.norm(u, axis=1)

plotter = pv.Plotter(off_screen=True)
plotter.add_mesh(m.grid, style="wireframe", color="#888888", opacity=0.3)
plotter.add_mesh(warped, scalars="|u|", cmap="viridis", show_edges=False)
plotter.view_isometric()
plotter.camera.zoom(1.1)
plotter.show()
example verify cantilever eb

Acceptance#

finest = rec.results[-1]
assert finest.passed, (
    f"finest-mesh tip_deflection failed: {finest.rel_error:.2%} "
    f"above tolerance {finest.published.tolerance:.0%}"
)

Total running time of the script: (0 minutes 1.747 seconds)

Gallery generated by Sphinx-Gallery