CAE仿真的回归测试 — 求解器更新·模型变更时的品质保证战略
理论与背景
CAE回归测试是什么
老师,回归测试(Regression Testing)是软件开发中的术语吧? CAE领域也要用吗?
很好的问题。在软件开发中"修改代码后检查其他功能是否破损"是回归测试,CAE领域中概念完全相同。
CAE中的回归测试是指,当求解器版本升级、模型变更、网格重新生成或操作系统·编译器更新等改变解析环境时,自动将过去"正确"的结果(基准线)与新结果进行比较,验证差异是否在许容范围内的流程。
也就是说,"虽然进行了变更,但前后结果应该相同"这一点要系统地验证对吧?
正是这样。比如汽车制造商进行碰撞仿真分析,LS-DYNA从R12升级到R13时,过去认可的模型的加速度峰值和侵入量是否变化——需要手动逐个验证这些数百个模型是不现实的。
确实,手工全部检查一周时间都不够…
所以要自动化。自动运行基准问题群,自动比较结果,超过阈值时发出警告——这就是CAE回归测试的全景图。
为什么需要回归测试
但求解器是商业软件吧?版本升级后结果会差很多吗?
会差的,而且差不少。 求解器厂商版本升级时会进行bug修复、算法改进和默认设置变更,这些都可能影响结果。
实际发生过的案例:
- Nastran版本变更导致固有频率变化0.3~0.5%(刚度矩阵组装算法改变)
- Abaqus小版本更新改变了接触判定默认设置,接触力变化数%
- OpenFOAM版本变更乱流模型壁面函数实现修正,Cd值变化超过2%
- 仅编译器优化标志变更就会改变浮点运算舍入顺序,非线性分析收敛路径分叉
哇,仅编译器优化标志就会让结果变化!这有点可怕…
正因如此回归测试必不可少。航空航天、原子能等涉及安全认证的领域,每次升级求解器版本都要运行所有认证基准问题是标准运维。汽车碰撞安全也要持续验证与NCAP基准的一致性。
判定的数学框架
"结果未变化"如何具体判定?数值不会完全相同对吧?
完全正确。浮点运算不会完全一致,而是用相对误差或绝对误差在许容范围内判定。基本公式是:
其中 $Y_{baseline}$ 为基准线结果,$Y_{new}$ 为新环境结果。判定标准:
当 $Y_{baseline}$ 接近零时相对误差会发散,此时用绝对误差:
基准线接近零的情况,比如约束点的位移(理论为零)之类?
正是这样的情况。实务中常用相对误差与绝对误差混合判定:
另外还要管理整个测试套件的合格率:
整个测试套件也有合格率基准吗?
许多组织将合格率100%定为发布条件。只要有1项不合格就要调查原因,判断是"有意改进的变化"还是"bug"。有意改进的话更新基准线。
求解器版本变更的影响
各求解器版本变更时通常影响哪些物理量,能再具体说明吗?
| 求解器 | 易出现变化的内容 | 典型差异大小 | 注意事项 |
|---|---|---|---|
| MSC Nastran | 刚度矩阵数值积分精度变更 | 固有频率 0.1~0.5% | SOL 103/111特别需注意 |
| Abaqus | 接触算法默认设置变更 | 接触力 1~5% | Release Notes中的"改变的默认值"必读 |
| Ansys Mechanical | APDL内部命令行为变更 | 应力 0.5~2% | Workbench中容易被隐藏 |
| OpenFOAM | 乱流模型·壁面函数实现修正 | Cd/Cl 1~3% | v.com与Foundation版本差异大 |
| LS-DYNA | 沙漏控制默认值变更 | 加速度峰值 2~10% | 碰撞仿真影响大 |
LS-DYNA加速度峰值最大变化10%!碰撞安全岂不是大问题…
确实大问题。所以汽车制造商CAE部门在求解器主版本更新时,要对数百个碰撞模型进行回归测试。人命关天的领域不允许马虎。
回归测试判定具体示例
Nastran v2024升级到v2025的回归测试结果示例。许容差按情况设定。
| 评估项目 | v2024(基准线) | v2025(新版本) | 相对误差 [%] | 判定 |
|---|---|---|---|---|
| 悬臂梁最大位移 | 5.234 mm | 5.231 mm | 0.06 | 合格 |
| 板的1阶固有频率 | 142.35 Hz | 141.89 Hz | 0.32 | 合格 |
| 螺栓接触力 | 12,450 N | 12,870 N | 3.37 | 不合格 |
| 整体能量守恒 | 99.97% | 99.96% | 0.01 | 合格 |
| 最大von Mises应力 | 325.8 MPa | 326.1 MPa | 0.09 | 合格 |
判定标准:相对误差 < 1%:■ 优秀,1~3%:■ 需要关注,> 3%:■ 不合格(必须调查原因)
基准线管理与许容差设计
基准线结果管理
"基准线"具体是什么数据,怎样管理?文件服务器上用Excel存储吗?
用Excel管理绝对不行(笑)。基准线管理的铁则是"在版本管理库中用机器可读格式保存"。
具体来说,结构应该是:
- Git库中存储基准线JSON或CSV
- 各基准线附带元数据:求解器名称·版本、执行日期、网格尺寸、操作系统/编译器信息
- 结果值是标量值提取结果(最大位移、最大应力、固有频率、反力合计等)
- 必要时场数据(节点位移分布、应力等高线)也用二进制格式保存
也就是说,从求解器输出文件(.f06、.odb等)中提取必要数值,而不是直接保存输出文件。
正是。求解器输出文件可能数GB大,保存成JSON格式的标量值的话,Git的差异显示也能有效工作,机器比较也容易。格式如下:
{
"model": "cantilever_beam_001",
"solver": "MSC Nastran",
"solver_version": "2024.1",
"date": "2026-01-15",
"os": "RHEL 8.9",
"results": {
"max_displacement_mm": 5.234,
"max_vonmises_mpa": 325.8,
"freq_mode1_hz": 142.35,
"reaction_force_n": 1000.02,
"energy_balance_pct": 99.97
}
}
许容差基准设计
许容差怎样设定?全部统一为0.1%的话比较简单…
统一的话问题很大。物理量的数值敏感性完全不同,所以根据物理量种类和对设计判定的影响来设定许容差。
| 物理量 | 推荐许容差 $\varepsilon_{rel}$ | 原因 |
|---|---|---|
| 位移(全局) | 0.1~0.5% | 由刚度主导,比较稳定。变化小 |
| 应力(最大值) | 1~5% | 网格依赖性强。奇异点附近变化大 |
| 固有频率 | 0.5~2% | 由质量和刚度平衡决定。比较稳定 |
| 反力合计 | 0.01~0.1% | 由力的平衡决定。非常稳定 |
| 接触力 | 2~10% | 强烈依赖接触算法。求解器间差异大 |
| CFD 阻力系数 Cd | 1~3% | 依赖乱流模型和网格 |
| 温度(最大值) | 0.5~2% | 导热比较稳定,但对流项变化 |
应力和接触力许容差较宽。仅改网格时应力值就变化很大呢。
这个认识是对的。还有重要一点,与安全系数相关的量要设置更严格的基准。比如疲劳寿命评估用的应力值,需要比其他物理量更严格的基准。
多阶段判定的思路
只有合格/不合格两个状态的话,稍微超过阈值就全部变为不合格吧?
很好的指摘。实务中常用3阶段判定:
- 绿色(合格):$e_{rel} < \varepsilon_1$ — 无问题。自动承认
- 黄色(警告):$\varepsilon_1 \leq e_{rel} < \varepsilon_2$ — 需确认。工程师审查后判定
- 红色(不合格):$e_{rel} \geq \varepsilon_2$ — 不合格。阻止发布
黄色作为缓冲区。信号灯的概念很容易理解。
比如固有频率,$\varepsilon_1 = 0.5\%$,$\varepsilon_2 = 2\%$ 的话,0.5%以下自动合格,0.5~2%由工程师手工确认,2%以上阻止发布——这种运维很常见。
实践:测试套件的构建
测试用例的选择
回归测试选哪些模型?社内所有模型都跑一遍太不现实吧。
全部跑的话计算成本太高,需要战略性地设计测试套件(测试用例集)。选择要点:
- 第1级:理论解已知的基准问题 — NAFEMS基准、悬臂梁、圆孔板等。验证解析基本功能是否破损
- 第2级:社内标准模型 — 过去项目中反复使用的模型。涵盖业务中重要的解析类型
- 第3级:边界情况 — 非线性接触、大变形、多物理场等,求解器变更易受影响的高难度模型
- 第4级:大规模模型(冒烟测试) — 数百万自由度级别。检查能否完成运行及内存使用量
第1级到4级分层。一般需要准备多少个用例?
规模和解析类型决定,20~100个左右是实务目标。汽车OEM的结构解析部门约50个,航空航天求解器认证可达200多个。重要的不是数量,而是覆盖所用求解器功能。
Python自动比较脚本
Python实现自动比较具体是什么样的代码?
pytest + NumPy的组合是标准做法。下面是简单的回归测试例子:
import json
import numpy as np
import pytest
def load_results(filepath):
with open(filepath) as f:
return json.load(f)
TOLERANCES = {
"max_displacement_mm": {"rel": 0.005, "abs": 1e-4}, # 0.5%
"max_vonmises_mpa": {"rel": 0.03, "abs": 0.1}, # 3%
"freq_mode1_hz": {"rel": 0.01, "abs": 0.01}, # 1%
"reaction_force_n": {"rel": 0.001, "abs": 0.01}, # 0.1%
"energy_balance_pct": {"rel": 0.001, "abs": 0.01}, # 0.1%
}
baseline = load_results("baseline/cantilever_001.json")
current = load_results("results/cantilever_001.json")
@pytest.mark.parametrize("key", TOLERANCES.keys())
def test_regression(key):
b = baseline["results"][key]
c = current["results"][key]
tol = TOLERANCES[key]
if abs(b) > 1e-12:
rel_err = abs(c - b) / abs(b)
assert rel_err < tol["rel"], \
f"{key}: rel_err={rel_err:.6f} > {tol['rel']}"
else:
abs_err = abs(c - b)
assert abs_err < tol["abs"], \
f"{key}: abs_err={abs_err:.6e} > {tol['abs']}"
用pytest参数化为各物理量做测试。一个用例失败也不影响其他的,报告自动生成。
对。pytest --junitxml=report.xml 运行就会生成,Jenkins或GitLab CI能自动识别结果。
测试结果报告的自动生成
测试结果要报告给上级或客户。报告也自动化吗?
当然。pytest-html 能生成HTML报告,更高级的可视化用 matplotlib + Jinja2模板 脚本自动生成PDF报告。
报告应包含内容:
- 测试执行日期·环境信息(求解器版本、操作系统、主机名)
- 全部测试用例的 合格/黄色/不合格 一览表
- 不合格用例的详情(基准线值、本次值、差值、许容差)
- 全体合格率与前次执行对比的趋势图
- 不合格原因分析(RCA)章节(手工输入)
CI/CD管道集成
Jenkins / GitLab CI / GitHub Actions对比
CI/CD是Web开发工具吧?CAE也能用吗?
反而CAE更需要。解析模型输入文件(.bdf、.inp等)用Git管理,Push时自动运行求解器并进行回归测试——这样的工作流一旦建立,品质保证效率会大幅提升。
| 工具 | 特点 | CAE适用度 | 说明 |
|---|---|---|---|
| Jenkins | 本地部署。插件丰富 | ★★★★★ | HPC集成最灵活。大型汽车·航空宇宙有众多实绩 |
| GitLab CI | 与GitLab集成。Runner自部署 | ★★★★☆ | 自托管Runner可连接社内HPC集群 |
| GitHub Actions | GitHub云托管。易上手 | ★★★☆☆ | 云Runner中商用软件许可问题突出 |
| Azure DevOps | 企业级 | ★★★★☆ | Azure HPC集成。适合大型组织 |
Jenkins评分最高为什么?
两个原因。一是与本地HPC集群集成最灵活,可与商用求解器许可证服务器同一网络。二是作业调度自定义性高。CAE作业单个用例要运行数小时,与Web开发的秒级作业大不相同,需要精细的并行度和队列控制。
求解器别的自动化手法
求解器每个都自动运行方法不一样吧?
| 求解器 | 批处理执行命令 | 结果提取方法 |
|---|---|---|
| MSC Nastran | nastran input.bdf | .f06文本解析 或 pyNastran (.op2读取) |
| Abaqus | abaqus job=model | abaqus python (.odb读取) 或 odb2vtk转换 |
| Ansys Mechanical | ansys -b -i input.ans | APDL /POST1输出 或 dpf-core (Python) |
| OpenFOAM | ./Allrun | postProcess -func, foamDictionary |
| LS-DYNA | ls-dyna i=input.k | lsprepost批处理 或 Qd/Lasso (Python) |
pyNastran、dpf-core初次听说。可以Python直接读结果?
可以。最近各求解器厂商都提供Python API,结果文件能直接从Python读。pyNastran是开源库,能读取Nastran的.op2文件;Ansys DPF (Data Processing Framework)是Ansys结果后处理Python库;Abaqus也有odbAccess模块从Python打开.odb。
典型的Jenkins管道流程是:
- 触发:Git输入文件Push或定时计划(每晚、每周)
- 构建:求解器批处理执行(通过HPC作业调度)
- 测试:Python脚本与基准线自动比较(pytest)
- 报告:HTML/PDF报告生成,通知Slack
- 归档:测试结果保存为Jenkins artifact
大规模组织中的CI/CD运维
汽车制造商这样的大组织怎样运维?
大型汽车OEM的CAE部门通常这样做:
- 每晚自动运行:全部测试套件(50~200个)自动执行。次日早上生成报告
- 求解器版本评估:新版本发布时,2~3人专项小组用2~4周评估全部测试套件,调查不合格原因
- 门卫制度:求解器版本社内推广前,"CAE平台团队"必须验证全件合格
- 基准线更新流程:不合格原因判为"有意改进"时,2名以上工程师审查后才能更新基准线
基准线更新也要审查啊。不然基准本身的意义就失去了。
正是。基准线更新时要文档化"为什么变化"的技术根据。记录在Git提交信息或issue跟踪工具中,这样后来审计和追溯才能做到。
先进课题
机器学习异常检知
现在AI和机器学习也用于回归测试吗?
先进的组织开始采用。传统的"标量值阈值比较"之外,对场数据(应力分布、变形形态)进行统计比较时开始用ML。
具体手法:
- 主成分分析(PCA):场数据降维,计算与基准线的"距离"。标量值无法检出的图案变化能发现
- 自编码器:学习正常图案,新结果的"重构误差"大则判异常
- 时序异常检知:历次测试结果追踪,如果数值跨多个版本有统计意义的漂移就发警
"结果逐渐漂移"是什么情况?好几个版本跨度慢慢变化吗?
正是。一次版本更新只变0.1%,5次重复就累积0.5%。单次都在阈值以下易忽视,但时序分析能警告"这个值存在明显漂移趋势"。
云HPC的联动
云HPC(AWS HPC等)用于回归测试怎样?
云HPC(AWS ParallelCluster、Azure CycleCloud、Google Cloud HPC Toolkit)与集成的速度在加快。优势是测试套件全用例能同时并行。本地HPC用满了可能排队,云能随需扩展。
课题还是商用求解器许可证。不少商用软件开始提供云用柔性许可,但成本模型(按用量、令牌制)与传统不同。OpenFOAM这样的开源求解器没有这问题。
CAE仿真回归测试的故障排除
回归测试特有的陷阱
老师,回归测试运维中常见问题有哪些?
| 问题 | 原因 | 对策 |
|---|---|---|
| 假阳性太多 | 许容差过严。浮点舍入误差级别差异频繁导致不合格 | 按物理量重新设计适切许容差。CFD乱流统计量要宽松 |
| 假阴性 | 许容差过松。重要差异被漏检 | 安全相关物理量的许容差重新审查。活用黄色区间 |
| 基准线污染 | 环境变更每次都随意更新基准,失去原有正确性 | 严格执行基准线更新审批流程和文档化 |
| 测试执行时间膨胀 | 用例太多,全件运行需数天 | 分级测试,日间轻量级,周间全量 |
| 非再现性 | 并行计算的执行顺序、随机数种子、舍入误差每次略有不同 | 并行度固定、随机数种子统一、对非决定性差异设置专用许容差 |
非再现性很麻烦呢。同一模型、同一机器,运行2遍结果还不一样?
MPI并行执行时,进程通信时序会改变浮点加法的顺序。$a + b + c$ 与 $b + c + a$ 理论相同,但舍入误差致最后位数变化。非线性问题中这微小差异能改变牛顿·拉夫森法的收敛路径。
对策:
- 固定并行度(4核就始终4核)
- 求解器选项启用再现性模式(Nastran的
SYSTEM(207)=1等) - 微小差异设置专用的宽松许容差
版本变更时的应急对应
求解器升级后回归测试大量不合格怎么办?很恐慌…
先冷静。然后按这个流程处理:
- 分析不合格的图案:都是同种物理量?同一元素类型?同种解析类型?有图案就缩小范围
- 查阅Release Notes:厂商的Release Notes里"改变的默认值"或"修复的bug"通常有说明。许多不合格就此得解
- 制作最小再现用例:复杂模型的不合格,简化到1单元模型找原因快
- 联系厂商:自己无法特定原因,提交不合格用例输入文件和两版本结果给技术支持
- 判定:"bug修复带来的改善"就更新基准线。"新bug嫌疑"就延期升级,继续用旧版本
图案分析、Notes查阅、最小用例、厂商问询——逻辑系统的对应啊。
还有重要一点,维持能回滚的体制。求解器要新旧版本并行装,问题出现时能立即切换回旧版本。这需与基础设施团队事先协调。
今天关于回归测试学了不少。基准线管理、许容差设计、Python自动化、CI/CD、故障对应——整体思路清楚了。明天开始在我们团队构建这个体制!
好主意。最初不用做完美,从5个基准问题和Python脚本开始,逐步扩展。小处着手,稳步成长是诀窍。加油!
有用
更详细
报告