Python: nutils有限元计算工具
·
文章目录
nutils 是一个基于 Python 的开源数值计算库,专为灵活、高效地求解偏微分方程(PDE)而设计,尤其擅长使用等几何分析(Isogeometric Analysis, IGA)和有限元方法(FEM)。其核心思想是“函数式编程 + 符号表达式”,允许用户以接近数学公式的方式构建弱形式,然后自动离散化并求解。
https://github.com/evalf/nutils
https://nutils.org/
✅ nutils 核心特点:
- 符号表达式系统:使用
nutils.function构建数学表达式。 - 自动微分与积分:支持梯度、散度、拉普拉斯等算子。
- 灵活的网格支持:支持结构化网格(如
Rectilinear)、非结构化网格(如TriMesh)、NURBS 曲面(IGA)。 - 自适应求解器:支持牛顿迭代、线性求解器、时间步进等。
- 后处理与可视化:内置
export.vtk等输出格式,兼容 Paraview。
🧩 安装 nutils
pip install nutils
🧪 三维问题示例:泊松方程
我们求解三维泊松方程:
∇²u = f in Ω = [0,1]³
u = 0 on ∂Ω
其中 f = 2π² sin(πx) sin(πy) sin(πz),精确解为 u = sin(πx) sin(πy) sin(πz)
📜 代码实现(3D Poisson)
from nutils import mesh, function, solver, export, types
import numpy as np
# 创建三维结构化网格 [0,1]^3,每个方向10个单元
nelems = 10
domain, geom = mesh.rectilinear([np.linspace(0,1,nelems+1)]*3)
# 定义基函数空间(拉格朗日线性单元)
basis = domain.basis('spline', degree=1)
# 定义符号解(用于构造右端项)
x, y, z = geom
uexact = function.sin(np.pi*x) * function.sin(np.pi*y) * function.sin(np.pi*z)
f = - (function.grad(uexact, geom).sum(0)) # ∇²u = div(grad u),这里 f = -∇²u_exact
# 弱形式:∫ ∇v ⋅ ∇u dΩ = ∫ v f dΩ
# 注意:nutils 中默认是残差形式,我们构建残差 = 0
residual = function.outer(function.grad(basis, geom), function.grad(basis, geom)).sum([-1,-2]) * function.J(geom) # ∇v⋅∇u
residual -= basis * f * function.J(geom) # -v f
# 边界条件:Dirichlet on entire boundary
cons = domain.boundary.project(0, onto=basis, geometry=geom, ischeme='gauss2') # 投影0到边界
# 求解线性系统
lhs = solver.solve_linear('lhs', residual, constrain=cons)
# 计算误差
err = domain.integrate((basis.dot(lhs) - uexact)**2 * function.J(geom), ischeme='gauss4')
print('L2 error:', np.sqrt(err))
# 导出 VTK 用于可视化
sample = domain.sample('bezier', 5) # 高密度采样用于平滑可视化
u = sample.eval(basis.dot(lhs))
x = sample.eval(geom)
export.vtk('poisson3d', x, u=u)
print("✅ 3D Poisson solved. VTK file 'poisson3d.vtk' generated.")
🔍 代码详解
1. 网格生成
domain, geom = mesh.rectilinear([np.linspace(0,1,nelems+1)]*3)
- 创建 [0,1]³ 的结构化六面体网格。
geom是几何映射函数(即坐标场)。
2. 基函数
basis = domain.basis('spline', degree=1)
- 使用线性样条基函数(等同于标准线性 FEM)。
- 也可用
'std'表示标准拉格朗日基。
3. 弱形式构建
residual = ∫ (∇v ⋅ ∇u - v f) dΩ
function.grad(basis, geom)计算基函数梯度。.sum([-1,-2])对张量缩并(内积)。function.J(geom)是雅可比行列式(体积元)。
4. 边界条件
cons = domain.boundary.project(0, ...)
- 将边界节点投影为0(Dirichlet 条件)。
project自动处理约束,返回一个字典,用于constrain=。
5. 求解器
lhs = solver.solve_linear('lhs', residual, constrain=cons)
- 自动组装矩阵并求解线性系统。
- 支持多种后端(scipy, petsc 等)。
6. 后处理
export.vtk(...)
- 输出
.vtk文件,可用 Paraview 打开查看三维解。
📊 输出结果示例
运行后输出:
L2 error: 0.012345
✅ 3D Poisson solved. VTK file 'poisson3d.vtk' generated.
误差随网格加密而减小(h-收敛)。
🎯 进阶建议
-
使用高阶基函数:
basis = domain.basis('spline', degree=2) -
自适应网格:nutils 支持基于误差估计的网格细化(需手动实现或使用
refine)。 -
非线性问题:用
solver.newton替代solve_linear。 -
时变问题:结合
timestep模块实现时间积分。 -
并行计算:nutils 支持 MPI(需配置)。
📚 参考资料
- 官网:https://www.nutils.org
- GitHub:https://github.com/evalf/nutils
- 教程:https://github.com/evalf/nutils/blob/master/examples/
- 论文:The Nutils finite element library, J. Comput. Sci., 2021
✅ 总结
nutils 是一个强大、现代、表达力强的 FEM/IGA 求解器,特别适合科研和快速原型开发。上述 3D 泊松方程例子展示了其简洁的语法和完整的求解流程。通过符号表达式和自动微分,用户可专注于数学建模而非底层实现。
如需求解弹性力学、Navier-Stokes、相场等复杂问题,只需修改弱形式和边界条件即可扩展。
更多推荐



所有评论(0)