Note
Go to the end to download the full example code.
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()

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)