CAE极客坊 · 用代码解放仿真工程师
如果你写过 Abaqus Python 脚本,大概率经历过这个场景:
脚本写好了,跑通了,交付给同事。同事打开同一个STEP文件,faces[3]选中的面变了。脚本直接报错或选错位置。
不是你的代码有bug,不是Abaqus版本不对——是几何编号本身就不稳定。
这个问题在Abaqus二次开发的圈子里几乎人尽皆知,但奇怪的是,网上几乎没有一篇系统讲清楚"为什么"和"怎么治"的文章。教程都在教你怎么调API,好像这个坑不存在一样。今天这篇,我把它彻底拆开。
一、问题复现:同一个模型,编号居然会变
我用CadQuery建了一个L型支架,导出为STEP,然后分别用Abaqus直接导入和先导入再导出两种方式处理。结果:
同一个几何,faces[3]从"左侧固定面"变成了"右侧倒角面"。你脚本里写的faces[3]选的是两个完全不同的东西。
这不是偶发。B-Rep(边界表示法)内核在解析STEP文件时,面的遍历顺序取决于拓扑展开算法的内部状态——不同的CAD内核(ACIS、Parasolid、OCC)遍历同一棵拓扑树的顺序不同,甚至同一个内核的不同版本都可能变。
STEP文件不记录面的编号顺序。编号是导入时即时生成的,而且不可预测。
▼ 图1:同一个L型支架,重新导入后faces[3]变成了不同的面
二、为什么findAt也救不了你
有人会说:我知道按索引选不靠谱,所以我用findAt,按坐标选面总行了吧?
face = part.faces.findAt((0.0, 0.0, 0.0))
findAt确实比裸索引稳定——如果你的几何是规整的、面中心恰好是整数坐标的话。但它有三个致命弱点:
弱点1:坐标会随参数变你用参数化模板,板长从100改到200,面的中心坐标就变了。findAt((50, 0, 0))直接失效。你得在每个参数组合下重新算坐标——本质上是在手动维护一层脆弱的坐标映射。
弱点2:多个面共享同一坐标L型支架的内拐角处,两个面在同一个坐标点交汇。findAt返回第一个匹配的,可能是你想要的,也可能不是。取决于面在B-Rep树里的排列顺序——又绕回去了。
弱点3:曲面中心难计算对于圆柱面、自由曲面,面中心在哪?你得自己算几何重心。算错了findAt直接返回None,脚本静默失败。
▼ 图2:三种面选择方案的稳定性对比
三、真正的解法:语义锚点
根本解法是——放弃用几何信息(索引、坐标)定位面,改用语义信息定位。不要告诉程序"选第3个面",而是告诉它"选安装面"。
第1步:定义一套语义命名规范
这套词表是封闭的——只有几十个标准token,类型(约束/载荷/接触/区域)+位置(左/右/上/下/端部)的组合,覆盖大部分常见CAE场景。
▼ 图3:语义锚点命名规范——封闭词表的组合
第2步:首次建模时,人工选面建Set
工程师第一次打开模型时,人工选好每个面,创建命名Set。这一步30分钟,一劳永逸。之后所有脚本只引用Set名字,永远不碰faces[索引]。
第3步:脚本里只引用Set名
# ❌ 脆弱写法face = part.faces[3]# 编号变了就崩# ❌ 半脆弱写法face = part.faces.findAt((50.0, 0.0, 0.0))# 参数变了就崩# ✅ 稳健写法face = part.sets['SET_CLAMP_LEFT'].faces[0]# 名字不变就不崩
好处是:几何怎么变都行,只要语义不变,脚本就稳定。
四、进阶:三套面识别方案
人工建Set适合有模板的重复分析。但如果遇到全新几何,没有现成模板呢?我在自己的工具链里实现了三套自动面识别方案:
▼ 图4:三套自动面识别方案对比
最实用的是特征匹配。即使面的编号完全变了,只要几何特征没变(同一个安装面还是那个安装面),就能重新定位。
五、这套思路怎么对接AI?
人工建Set解决的是"有模板"的场景。但遇到全新几何呢?答案是CBR(基于案例的推理):
新几何 → 提取面特征 → 案例库找最相似案例 → 借鉴BC模式 → 自动推荐Set命名
核心连接点:CBR检索用的"几何指纹"和面识别用的"特征向量"是同一套东西。面识别不是孤立功能,它是CBR推荐的基础设施。
这就是为什么我把几何编号问题放在系列最前面——它是整个Abaqus自动化工具链的地基,地基不稳,上面全白搭。
写在最后
回到开头那个场景:同事打开你的脚本,faces[3]变了,脚本崩了。解法一句话:
用语义锚点替代几何索引。编号会变,但名字不会。
CAE极客坊 · 机械博士,用代码把CAE全流程自动化。踩过的坑、跑通的方案、折腾出来的工具,都在这里。
如果这篇文章解决了你的困惑,欢迎点个在看。下一篇拆解Abaqus noGUI模式的正确用法——为什么openMdb不是你想的那样,以及怎么写出不依赖GUI的生产级脚本。