岩土力学:弹性条形基础¶
本示例为固体力学示例族增加一个小型岩土力学边值问题。一个线弹性土块由中心条形基础加载,然后用 TensorMesh 标准的直接线弹性流水线求解。
该示例刻意保持适度:它演示岩土边界条件、基础载荷块、沉降报告,以及反力/载荷平衡,而不引入公共岩土力学 API。
问题¶
该模型是二维平面应变式土块,面外厚度为单位 1。位移场满足小应变线弹性,
该域由限定在顶面块上的压缩为正的基础压力加载。在内部,载荷施加在负 y 方向。为岩土力学报告,沉降以向下为正显示,
边界条件¶
本示例使用简单的滚动支座设置:
底部边界:竖向位移固定,``u_y = 0``;
左右边界:水平位移固定,``u_x = 0``;
顶部边界:除受载基础块外自由。
基础压力被集总到基础块内的顶面节点上。这使示例贴近既有的固体力学直接求解示例,而合理性检验则验证总反力与总施加载荷平衡。
合理性检验¶
脚本报告总施加竖向载荷、固定竖向自由度处的竖向反力、反力/载荷相对误差,以及最大沉降。
相应的测试检查:
土体在基础下方向下沉降;
竖向反力与施加的竖向载荷平衡;
基础压力加倍约使沉降加倍。
图 57 elastic_footing.py 的输出。左面板显示按沉降 -u_y 着色的变形土网格;红色箭头标出基础载荷,蓝色标记显示基底的竖向支撑,紫色标记显示侧边界上的水平滚动约束。右面板显示沿地表的沉降剖面。最大沉降发生在中心基础下方,变形为便于观察被放大。¶
运行它¶
cd examples/solid/geomechanics/elastic_footing
python elastic_footing.py
若只想快速做纯数值运行而不写出图:
python elastic_footing.py --no-plot --chara-length 0.5
核心实现¶
完整驱动在 examples/solid/geomechanics/elastic_footing/elastic_footing.py。它复用与既有线弹性固体示例相同的直接求解组件:LinearElasticityElementAssembler、Condenser 和 SparseMatrix.solve。
problem: FootingProblem,
dtype: torch.dtype = torch.float64,
device: str | torch.device = "cpu",
) -> Dict[str, Any]:
"""Assemble and solve the elastic footing boundary-value problem."""
mesh = build_mesh(problem, dtype=dtype, device=device)
assembler = LinearElasticityElementAssembler.from_mesh(
mesh,
E=problem.E,
nu=problem.nu,
)
K = assembler()
fixed = make_boundary_mask(mesh, problem)
rhs, loaded_nodes, total_vertical_load = make_load_vector(mesh, problem)
rhs_flat = rhs.flatten()
condenser = Condenser(fixed.flatten())
K_cond, rhs_cond = condenser(K, rhs_flat)
u_cond = K_cond.solve(rhs_cond)
u_flat = condenser.recover(u_cond).to(dtype=rhs_flat.dtype)
u = u_flat.reshape(mesh.n_points, mesh.dim)
# Reactions at constrained DOFs: r = K u - f.
# SparseMatrix inherits @ from torch-sla SparseTensor.
residual = K @ u_flat - rhs_flat
reactions = residual.reshape(mesh.n_points, mesh.dim)
vertical_fixed = fixed[:, 1]
vertical_reaction = reactions[vertical_fixed, 1].sum()
uy = u[:, 1]
settlement = -uy
footing_settlement = settlement[loaded_nodes].mean()
max_settlement = settlement.max()
min_uy = uy.min()
load_balance_error = torch.abs(
vertical_reaction + torch.as_tensor(
total_vertical_load,
dtype=vertical_reaction.dtype,
device=vertical_reaction.device,
)
) / max(abs(total_vertical_load), 1.0)
result = {
"mesh": mesh,
"K": K,
"rhs": rhs,
"u": u,
"fixed": fixed,
"loaded_nodes": loaded_nodes,
"total_vertical_load_N_per_m": total_vertical_load,
"vertical_reaction_N_per_m": float(vertical_reaction.detach().cpu()),
"load_balance_relative_error": float(load_balance_error.detach().cpu()),
"max_settlement_m": float(max_settlement.detach().cpu()),
"footing_settlement_m": float(footing_settlement.detach().cpu()),
"min_vertical_displacement_m": float(min_uy.detach().cpu()),
"n_nodes": int(mesh.n_points),
"n_loaded_nodes": int(loaded_nodes.numel()),
"n_fixed_dofs": int(fixed.sum().detach().cpu()),
"n_free_dofs": int(fixed.numel() - fixed.sum().detach().cpu()),
}
return result
下一步¶
本示例是弹性的,且刻意保持小规模。后续可以用相同的基础几何复用示例局部的 Drucker-Prager 材料模型,或在 API 方向明确后把一个稳定化的岩土力学装配器提升进 tensormesh/assemble/。