构造解方法(MMS)概述与步骤

分类:V&V·构造解方法 | 2026-10-01 改写
CAE visualization for mms overview theory - technical simulation diagram
MMS(制造解法)的概述和步骤

理论:先确定解

概述

🙋

我想验证自己写的热分析代码,但热导率随温度变化的问题找不到精确解。怎么办?

🎓

用构造解方法(MMS)。把思路反过来,先决定“希望得到的解”。把这个解代入方程,左右两边就会有不相等的部分,把它作为源项加到方程中,决定的解就正好是该方程的解。然后在代码中加入该源项求解,确认网格加密时误差是否按格式理论速度减小。关键是用误差的减小方式判断,而不是看解是否看起来对。

例题方程

$$ -\frac{d}{dx}\left(k(u)\frac{du}{dx}\right) = f(x), \qquad k(u) = 1 + u^2, \qquad u_{MMS} = \sin(\pi x) + x $$

热导率依赖于解的非线性扩散方程。构造解光滑,在两端分别为0和1。

源项与收敛阶

$$ f(x) = -\frac{d}{dx}\left(k(u_{MMS})\frac{du_{MMS}}{dx}\right), \qquad p_{obs} = \frac{\ln(e_{2h}/e_h)}{\ln 2} $$

用符号计算(如sympy)求源项,可以避免手算错误。由网格间距减半时的误差之比求表观收敛阶。

Coffee Break 随笔闲谈

逆向思维:构造解

有解析解的问题数量有限,几乎不适用于实际软件所处理的非线性、多维、复杂边界方程。20世纪80年代Steinberg和Roache提出先确定解、用源项使方程成立的方法,21世纪初Roache、Salari、Knupp等人将其整理为程序验证的标准步骤。如今广泛用于包括湍流模型的流体代码以及固体、热、电磁软件的验证,ASME验证标准也把它作为代码验证的核心方法。

算例:发现小bug

用有限差分比较两种实现:正确实现在面上用两侧平均值计算热导率,错误实现只用左侧值(一个字符的差别)。用Picard迭代求解,求节点最大误差:

分段数正确实现误差阶数错误实现误差阶数
101.13×10⁻²—4.62×10⁻²—
202.85×10⁻³1.982.13×10⁻²1.11
407.10×10⁻⁴2.001.04×10⁻²1.03
801.78×10⁻⁴2.005.15×10⁻³1.02
1604.44×10⁻⁵2.002.56×10⁻³1.01
🙋

错误实现误差也只有1%左右,而且随网格加密减小。这样恐怕察觉不到。

🎓

这正是MMS的长处。只看误差大小,错误实现也像是“大致对、加密就会变好”,画成图几乎与构造解重合。但误差减小方式明显不同:正确实现为二阶,错误实现为一阶。在面上用单侧值计算系数,使本应二阶的格式混入了一阶误差。实际问题中,这种差别会作为细网格下也不消失的百分之几误差残留。MMS通过阶数这一数字,让看不出的错误浮现出来。

步骤与技巧

  1. 选择使所有项(对流、扩散、源、非线性系数)都起作用的构造解;过于简单的解会掩盖错误。
  2. 用符号计算求源项和边界条件,自动输出到代码中。
  3. 在四级以上网格上求解,求误差范数和阶数。
  4. 改变边界条件、网格类型和非线性迭代设置,逐一确认。
  5. 把结果做成自动测试,每次修改代码都确认阶数。
Coffee Break 随笔闲谈

“只有边界是一阶”

用MMS验证某流体代码时,内部网格点误差按二阶减小,整体最大误差却只按一阶减小。看误差分布,只有紧邻壁面边界的点误差大,边界条件实现为一阶精度——壁面梯度用了一阶单侧差分近似。改为二阶单侧差分后整体变为二阶。MMS中不仅看误差大小,还看分布,就能定位错误所在。

常见错误

错误与对策

错误后果对策
只凭误差大小判断漏掉阶数下降务必求阶数
构造解过于简单部分项不起作用,错误被掩盖使所有项起作用
手算源项源项本身出错用符号计算自动化
迭代收敛不充分阶数紊乱严格收敛判据
只用两套网格判断不知道是否处于渐近范围四级以上
🙋

我想了解相关内容。

🎓
关联模拟器

在本领域的交互式模拟器中体验理论

模拟器列表

相关分析领域

结构分析流体分析(CFD)热分析
本文评价
感谢您的反馈!
有帮助
更详细
报错
有帮助
0
更详细
0
报错
0