悬臂梁

TensorMesh 中固体力学的教科书式入门示例:一根 \(2.0 \times 0.2 \times 0.2\) m 的钢制悬臂梁,一端固定,另一端施加向下的力。线性小应变弹性,一次直接线性求解,约 30 行代码。脚本位于 examples/solid/cantilever_beam/cantilever_beam.py

问题

小应变线弹性:

\[\nabla \cdot \boldsymbol{\sigma} \;=\; \mathbf{0} \quad \text{in } \Omega, \qquad \boldsymbol{\sigma} \;=\; \mathbb{C} : \boldsymbol{\varepsilon}, \qquad \boldsymbol{\varepsilon} = \tfrac12 (\nabla\mathbf{u} + \nabla\mathbf{u}^T),\]

其中 \(\mathbb{C}\) 是各向同性刚度张量,杨氏模量 \(E = 200\) GPa,泊松比 \(\nu = 0.3\)。边界条件:

  • \(x = 0\) 处固定:\(\mathbf{u} = \mathbf{0}\)

  • \(x = 2\) 处的端部载荷:总力 \(F = -100\) kN,分布于右端面节点上,

  • 其余所有表面:无面力(自由)。

TensorMesh 设置

完整的驱动脚本:

列表 9 examples/solid/cantilever_beam/cantilever_beam.py
from tensormesh import Mesh, Condenser
from tensormesh.dataset.mesh import gen_cube
from tensormesh.assemble import LinearElasticityElementAssembler
from tensormesh.material import Steel
from tensormesh.visualization import plot_deformation

# 1. Mesh
mesh = gen_cube(chara_length=0.08,
                left=0.0, right=2.0,
                bottom=0.0, top=0.2,
                front=0.0, back=0.2)

# 2. Material + stiffness assembly
K = LinearElasticityElementAssembler.from_mesh(
        mesh, E=Steel.E, nu=Steel.nu)()

# 3. Boundary conditions: clamp the x=0 face
eps = 1e-5
fixed_node_mask = torch.abs(mesh.points[:, 0]) < eps
fixed_dof_mask  = torch.repeat_interleave(fixed_node_mask, mesh.dim)
condenser       = Condenser(fixed_dof_mask)

# 4. Load: distribute -100 kN over the right-face nodes
right_mask  = torch.abs(mesh.points[:, 0] - 2.0) < eps
right_nodes = torch.where(right_mask)[0]
rhs = torch.zeros((mesh.n_points, mesh.dim))
rhs[right_nodes, 1] = -1e5 / right_nodes.shape[0]
rhs_flat = rhs.flatten()

# 5. Solve
K_, F_  = condenser(K, rhs_flat)
u_full  = condenser.recover(K_.solve(F_)).reshape(-1, mesh.dim)

# 6. Visualize the displaced mesh
plot_deformation(mesh, u_full,
                 save_path="cantilever_steel.png",
                 scale=50)

几个让代码如此简短的细节:

  • LinearElasticityElementAssembler 是一个内置的向量值装配器——它为每一对(测试、试探)基函数返回一个大小为 [mesh.dim, mesh.dim] 的刚度块,并将它们全部封装进一个形状为 [mesh.dim * n_points, mesh.dim * n_points]SparseMatrix。约定参见 形式

  • 自由度按节点排布为 [u_x, u_y, u_z]torch.repeat_interleave(fixed_node_mask, dim) 把逐节点的掩码提升为逐自由度的掩码。

  • tensormesh.material 提供了预定义的各向同性材料(SteelAluminumRubberBone),这样你就无需记忆 \(E\)\(\nu\)

  • plot_deformation 通过 scale=50 放大变形以便观察——实际的端部位移仅为毫米量级。

合理性检验

对于端部受载的等截面悬臂梁,欧拉-伯努利梁理论预测的端部挠度为

\[\delta \;=\; \frac{F\, L^3}{3\, E\, I}, \qquad I = \frac{b\, h^3}{12},\]

其中 \(L = 2\) m,\(b = h = 0.2\) m,\(E = 200\) GPa,\(F = 10^5\) N。由此得到 \(\delta \approx 5.0\) mm。有限元解在右端面中心处的结果应与之吻合,误差不超过粗网格的近似误差(在 chara_length=0.08 时为百分之几)。

钢制悬臂梁——端部受载下的变形形状,按位移着色

图 42 cantilever_beam.py 的输出。未变形的梁以浅灰色绘制;变形后的构型按位移大小着色。蓝色立方体标记 \(x=0\) 处的固定节点;红色箭头标记 \(x=L\) 面上分布的端部载荷。变形被放大了约 62 倍,以便在此长宽比下能看清弯曲——实际的端部位移仅为毫米量级,与欧拉-伯努利闭式解吻合,误差不超过粗网格的近似误差。

运行示例

cd examples/solid/cantilever_beam
python cantilever_beam.py     # writes cantilever_steel.png

控制台输出会以毫米为单位报告最大节点位移。

下一步

  • 形式 —— 向量值装配器的返回形状(每个求积点为 [dim, dim] 块)。

  • 边界条件 —— 针对向量未知量的自由度掩码。

  • 超弹性梁(新胡克) —— 几何风格相同的问题,但通过新胡克能量实现大变形。