去年Q3接了个电池包跌落仿真的活,显式动力学,模型127万个C3D8R单元,加上点质量模拟电芯、BMS板卡、线束卡扣,总共塞了46个Point Mass。
第一版模型提交之后跑了11个小时,算完了,我打开后处理一看位移云图,数据是有的,但总质量对不上。设计给的BOM表说整包38.7kg,我在CAE里用Query Mass Properties一查,显示31.2kg。差了7.5公斤。
我当时的第一反应是材料密度填错了。翻了Property模块里六种材料的密度值,全部核对,没问题。又怀疑是截面厚度赋错了,把壳单元厚度逐个查了一遍,也没问题。
折腾了一个下午,最后发现:Query Mass Properties压根不统计Point Mass。 那46个集中质量点加起来正好差7公斤左右。CAE界面上那个查询工具只算几何体积分乘以密度,通过Interaction模块添加的Point Mass/Inertia它不管。
这就是"凑合不了"的起点。如果你只靠CAE界面上那个Query按钮,你永远拿不到完整的质量数据。尤其做显式分析,质量缩放之后质量变化了多少、动能内能比值多少,这些东西界面上根本看不到,必须去翻文本文件或者写脚本。
路径:Mesh模块 → Mesh → Verify Part,或者 Property模块 → Tools → Query → Mass Properties。
优点: 不用写代码,点两下鼠标就出结果。网格质量会高亮显示不合格单元,直观。
我放弃它的理由:
第一,Query Mass Properties不含Point Mass,这在上面已经说了,做显式动力学或者装配体带配重块的场景,这个数据直接不可用。
第二,Mesh Verify的网格质量检查结果是显示在Message Area里的文字,不能导出、不能筛选、不能排序。127万个单元里挑出300个长宽比超标的,它给你打了一屏幕文字,你手动抄编号?不现实。
第三,它没有批量能力。我有六个工况、四套模型要检查,每个都手动点一遍Verify,纯体力活。
结论:小模型(10万单元以下)临时看一眼可以用,稍微上点规模就不够。
Abaqus的Python API里有个 part.checkMesh() 方法,能触发内置的网格检查逻辑。
我试了,放弃了。 原因是这个函数的返回值是一个状态码,不是数据对象。它把详细报表打印到stdout,也就是CAE底部的Message Area或者命令行窗口。你要拿到结构化数据(哪个单元编号、雅可比多少、长宽比多少),得自己重定向stdout再正则解析那段文本。
我试过把 sys.stdout 重定向到一个StringIO对象里,然后用正则匹配"Element XXX has aspect ratio YYY"这种格式的字符串。能跑,但极度脆弱——Abaqus不同版本打印的格式不完全一样,6.14和2022的措辞有差异,正则一改就断。维护成本太高,我用了两周就扔了。
不依赖checkMesh的文本输出,直接通过 mdb.models[...].parts[...].elements 拿到每个单元的节点坐标,自己算雅可比、长宽比、扭曲度,筛选出超标单元,写入CSV文件。
物理质量那边,提交一个Job之后从.dat文件里读"Total mass of model"那一行,这个数据包含所有质量定义(几何密度+Point Mass),是最完整的。
选这个方案的核心原因:数据可控、格式可控、能批量、能接进后续流程。 我后面把CSV直接喂给Excel做透视表,按区域统计不合格单元分布,给网格工程师发整改清单,整个链路是通的。

CAE模型(.cae)
│
├─→ [前处理检查] Python脚本遍历elements
│ │
│ ├─→ 计算jacRatio / 长宽比 / 扭曲度
│ │
│ └─→ 筛选超标单元 → 写入 mesh_quality_report.csv
│
├─→ [提交计算] Job Submit
│ │
│ ├─→ 生成 .dat 文件 → 搜索 "Total mass of model"
│ │
│ └─→ 生成 .sta 文件 → 搜索 "Percentage change in mass"
│
└─→ [后处理提取] openOdb读取场数据
│
└─→ 应力/位移统计 → 追加写入报告
from abaqus import *
from abaqusConstants import *
import math, csv
# ===== 调优参数区 =====
MODEL_NAME = 'Model-1'
PART_NAME = 'Battery_Pack_Assembly'
JAC_THRESHOLD = 0.6 # 雅可比下限,低于此值判定不合格(默认建议0.6,严格场景调到0.7)
AR_THRESHOLD = 5.0 # 长宽比上限,超过此值判定不合格(壳单元建议3.0,实体单元5.0)
OUTPUT_CSV = 'mesh_quality_report.csv'
# ========================
model = mdb.models[MODEL_NAME]
part = model.parts[PART_NAME]
bad_elements = []
with open(OUTPUT_CSV, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Element_Label', 'Jacobian_Ratio', 'Aspect_Ratio', 'Status'])
for elem in part.elements:
# 雅可比:API直接提供,0~1之间,越接近1越好
jac = elem.jacRatio()
# 长宽比:API没有直接属性,手动算边长极值比
nodes = elem.getNodes()
coords = [n.coordinates for n in nodes]
edges = []
for i in range(len(coords)):
for j in range(i + 1, len(coords)):
dist = math.sqrt(
sum((coords[i][k] - coords[j][k])**2 for k in range(3))
)
edges.append(dist)
if min(edges) > 1e-12:
ar = max(edges) / min(edges)
else:
ar = 999.0 # 退化单元,直接标红
status = 'OK'
if jac < JAC_THRESHOLD or ar > AR_THRESHOLD:
status = 'FAIL'
bad_elements.append(elem.label)
writer.writerow([elem.label, '%.4f' % jac, '%.2f' % ar, status])
# 汇总行
writer.writerow([])
writer.writerow(['Total_Elements', len(part.elements), '', ''])
writer.writerow(['Failed_Elements', len(bad_elements), '', ''])
print('Done. %d / %d elements failed.' % (len(bad_elements), len(part.elements)))
运行方式: CAE里 File → Run Script 选这个.py文件;或者命令行 abaqus cae noGUI=check_mesh.py 批量跑,不弹界面。
最靠谱的方式不是CAE界面,是提交Job之后翻.dat文件。
# 在工作目录打开 你的JobName.dat
# Ctrl+F 搜索:
Total mass of model
这一行后面跟的数字就是完整总质量,包含实体密度积分和所有Point Mass。我那个电池包案例,.dat里写的是38.714kg,跟BOM表的38.7kg对上了。
如果不想提交Job,前处理阶段可以用:
props = mdb.models['Model-1'].parts['Battery_Pack_Assembly'].getMassProperties()
print(props['mass']) # 注意:这个不含Point Mass
【调优标注】 getMassProperties() 只算几何体积×密度。如果你的模型有通过 Interaction → Special → Inertia → Point Mass 添加的集中质量,必须手动加回去。我现在的脚本里单独维护一个 point_mass_list = [1.2, 0.8, 0.35, ...],最后 total = props['mass'] + sum(point_mass_list)。
做了质量缩放之后,必须检查质量增量比例。路径:
打开工作目录下的 .sta文件(不是.msg,不是.dat),搜索:
Percentage change in mass
判定标准:
kinetic energy 和 internal energy 那两列。质量缩放的设置入口:Step模块 → 编辑Dynamic, Explicit分析步 → Other标签页 → Mass Scaling。选"Semi-automatic",类型选"If below minimum target",目标时间增量设一个值(我一般设1e-6秒)。这个参数的意思是:只有稳定时间增量小于这个值的单元才会被加质量,其余不动。 比"Scale to target"温和得多,不会把大单元的质量也改掉。

第一,Query Mass Properties的数据不要直接写进报告。
我第一版报告里写了"模型总质量31.2kg",评审专家当场问我"电芯质量去哪了"。我解释了十分钟Point Mass不被统计这件事,非常被动。现在的规矩是:报告里的质量数据一律从.dat文件取,CAE界面上的Query只用来做快速粗检,不作为正式数据来源。
第二,网格质量脚本不要在百万级模型上用纯for循环。
127万个单元,每个单元8个节点,两两算距离,内层循环28次。纯Python跑完要9分钟。我后来把坐标提取出来,用NumPy做向量化,同样的计算40秒跑完。如果你的模型超过50万单元,把节点坐标先dump成一个大数组,再批量算。
第三,.sta文件和.msg文件别搞混。
质量变化率在.sta里,收敛迭代信息在.msg里,模型摘要在.dat里。三个文件内容完全不同。我带过一个新人,让他查质量缩放比例,他翻了半小时.msg,跟我说"找不到"。.msg里确实没有这个信息。
第四,长宽比阈值不能一刀切。
实体单元长宽比5以下一般可以接受,但壳单元超过3就该警惕了,超过5基本会出问题。我脚本里的 AR_THRESHOLD 现在是按单元类型分开设的:C3D8R用5.0,S4R用3.0。如果你只设一个全局阈值,要么实体单元误报太多,要么壳单元漏检。
第五,显示精度和计算精度是两回事。
有人看到导入的CAD模型圆弧变成了多边形,以为网格质量差。不是。那是显示问题。Part模块 → View → Part Display Options → Geometry → Curve Refinement,从默认的Medium调到Fine或者Extra Fine,圆弧就平滑了。这个设置只改视觉呈现,不影响任何计算结果。 日常操作用Medium防卡顿,出图的时候调到Extra Fine截图就行。

脚本执行完毕,CAE底部打印:
Done. 347 / 1271856 elements failed.
打开生成的 mesh_quality_report.csv,前几行:
Element_Label, Jacobian_Ratio, Aspect_Ratio, Status
1, 0.9821, 1.23, OK
2, 0.9756, 1.41, OK
...
893412, 0.4213, 7.82, FAIL
893413, 0.3891, 9.15, FAIL
...
Total_Elements, 1271856, ,
Failed_Elements, 347, ,
347个不合格单元,占总量的0.027%。拿着这份CSV,按Element Label在CAE里 Mesh → Verify → Highlight elements by label 逐个定位,发现集中在电池包底板的四个螺栓孔倒角处——那里网格过渡区确实太密了,重新设种子拉过渡比例,重划之后降到29个,全部在可接受范围内。
.dat文件里的质量行:
Total mass of model = 38.7142E+00
.sta文件里的质量变化:
Percentage change in mass = 0.42
0.42%,低于1%的红线,质量缩放设置合格。
整套检查从提交到出报告,脚本跑完加人工核对,总共不到20分钟。之前手动翻文件、手动抄编号、手动算比例,同样的活要一个下午。