01列数决定一切
每种属性本身要占几列,是固定的。密度占 1 列,各向同性弹性占 2 列 (模量、泊松比),塑性占 2 列(屈服应力、塑性应变)。 判断规则只有一条:
实际列数 = 属性固定列数 + 1 → 多出来的最后一列是温度。
所以下面这两张表意思完全不同:
"density": { "table": [[7.85e-9], [7.8e-9]] }
→ 密度占 1 列,实际 1 列,不是温度相关
→ 两行都是「密度」,Abaqus 拿到两个互相矛盾的常数
"density": { "table": [[7.85e-9, 20], [7.8e-9, 400]] }
→ 密度占 1 列,实际 2 列,第 2 列是温度
→ 20 度时 7.85e-9,400 度时 7.8e-9第一种写法是真实发生过的错误:想写温度相关, 结果温度那一列漏了,两行就变成了两个打架的常数。 它不会被拦下来,因为每一行的列数是一致的,格式上完全合法。
反过来,如果各行列数不一致 —— 比如三行里有一行忘了写温度 —— 会被当场拦下:
thermal.conductivity: all rows must have the same length这条报错的前缀会跟着出错的属性变(density、elastic、plastic、thermal.specificHeat 等等),按前缀能一眼定位。
02各类属性的列数速查
把常用属性的固定列数列全,加一列就是温度相关的写法。 各向异性弹性那几行的常数个数是 Abaqus 定的,不能少也不能多。
| 属性 | 固定列数 | 各列的含义 | 温度相关时 |
|---|---|---|---|
| density | 1 | 密度 | 2 列 |
| elastic(各向同性) | 2 | 弹性模量、泊松比 | 3 列 |
| elastic type LAMINA | 6 | E1 E2 Nu12 G12 G13 G23 | 7 列 |
| elastic type ENGINEERING_CONSTANTS | 9 | E1 E2 E3 Nu12 Nu13 Nu23 G12 G13 G23 | 10 列 |
| elastic type ORTHOTROPIC | 9 | D 矩阵九个分量 | 10 列 |
| elastic type ANISOTROPIC | 21 | D 矩阵二十一个分量 | 22 列 |
| plastic | 2 | 屈服应力、塑性应变 | 3 列 |
| thermal.conductivity | 1 | 导热系数 | 2 列 |
| thermal.specificHeat | 1 | 比热 | 2 列 |
| thermal.expansion | 1 | 膨胀系数 alpha | 2 列 |
LAMINA 那一行是个好例子。示例库里的CFRP_IM7_8552_Lamina_TempDep 就是 7 列:
"elastic": {
"type": "LAMINA",
"temperatureDependency": true,
"table": [
[161000, 11380, 0.32, 5170, 5170, 3980, 20],
[152000, 9800, 0.32, 4400, 4400, 3400, 120]
]
}六个弹性常数加末尾的温度,一共 7 个数。 这是插件自带示例库里的演示值,用来说明格式。 复合材料的六个常数分别是什么、Nu12 和 Nu21 怎么区分, 在弹性模量与泊松比那篇里讲过。
03塑性表:每个温度都要重新从零开始
这是整篇里最容易错的一处。温度相关的塑性表不是一条连续的曲线, 而是每个温度一条独立的硬化曲线,各自都要从塑性应变 0 起步。
示例库里 Steel_S355_TempDep 的塑性表是这样的:
"plastic": {
"table": [
[355, 0, 20],
[450, 0.05, 20],
[300, 0, 400],
[380, 0.05, 400]
]
}四行分成两组:20 度那组从 (355, 0) 开始,400 度那组从 (300, 0)重新从 0 开始。第三行的塑性应变回到 0, 这不是笔误,是必须的。
plastic: the first plastic strain at temperature 400 must be 0, got 0.1报错串里会带上是哪个温度出的问题,直接定位到组。同一组内部还有两条要求,它们也是分组之后各组独立检查的:
- 塑性应变必须逐行递增,不能相等也不能倒退 ——
plastic: plasticStrain at temperature 400 must increase down the table, got 0.03 after 0.05 - 屈服应力必须是正的 ——
plastic: yieldStress at temperature 400 must be positive, got -300
注意这两条在没有温度列的时候也一样成立,只是报错串里少了 at temperature 那一段。非温度相关的塑性表三类报错, 在塑性表三类报错那篇里有完整的排查顺序。
还有一件事:屈服应力在高温下降低是正常的, 上面的例子里 355 降到 300 就是这个意思。 但插件不会因为高温组的应力比低温组低而报错 —— 它只在组内检查单调性,组与组之间不比较。 这是对的,因为强度随温度先升后降的材料确实存在。
04什么时候要显式写 temperatureDependency
大多数情况不用写,列数自己会说话。但显式写上有一个实在的好处:它会把列数校验从「按推断解释」变成「按声明核对」。
举个例子。你想写一个温度相关的 LAMINA,应该是 7 列, 但少打了一个数写成 6 列。
- 不写 temperatureDependency:6 列正好等于 LAMINA 的常数个数,于是被解释成「非温度相关的一行数据」, 悄悄导进去了。你以为建了两个温度点,实际只有一个。
- 写了 temperatureDependency: true:插件知道你要 7 列, 数出来 6 列,当场拦下:
elastic: type LAMINA with temperatureDependency true needs 7 values per row (6 constants plus a temperature), got 6
所以规则是:各向异性弹性建议都写上, 因为它们的常数多、列数容易数错,而且数错之后的两种解释都是合法的; 密度、塑性、导热这些一两列的属性,写不写差别不大。
elastic: type LAMINA needs 6 values per row, or 7 with a trailing temperature column, got 8这条报错本身就把两种合法列数都告诉你了,照着数一遍就能改对。顺带说一句,各向异性弹性的数值插件是不查的 —— 只查列数。正定性这类问题 Abaqus 要到建 Section 的时候才会说, 所以那道关得靠自己或者靠导入前的检查。
05温度单位:没有人会替你统一
表里的温度是摄氏还是开氏,Abaqus 不知道,插件也不校验 —— 它们看到的只是一串数字。这句话听起来像废话,直到你发现插件自带的示例库里两种单位是并存的:
| 示例材料 | 温度出现在哪 | 数值 | 看起来是 |
|---|---|---|---|
Steel_Q345 | 零应变参考温度 | 20 | 摄氏 |
Al_6061_T6 | 零应变参考温度 | 293 | 开氏 |
Steel_S355_TempDep | 各属性表的温度列 | 20 / 400 / 600 | 摄氏 |
后果不是导入报错,而是模型跑起来之后温度相关性完全错位。 材料表按摄氏写、初始温度场按开氏给,那么 293 K 的初始状态会去表里查 「293 度」,落在 20~400 那一段里靠后的位置,直接拿到接近 400 ℃ 的性能。 云图看着一切正常。
description 里注明这个材料用的是哪种温度单位。 这段文字会跟着材料一起进 Abaqus,在材料属性里看得到 —— 这是唯一一个能跟着数据走的地方。注释写在别处, 过两个月换个人接手就找不到了。零应变参考温度那个坑更隐蔽一点,它和这里的温度单位是同一类问题, 在热膨胀与零应变温度那篇里单独讲了。
06两个温度点之间,和两端之外
表给的是离散的几个温度点,实际计算中的温度几乎不会正好落在这些点上。 Abaqus 的处理方式是:
- 点与点之间:线性插值。20 度 E=210000、400 度 E=180000,那么 210 度时取两者的线性中值。 不管你给的是模量、导热系数还是屈服应力,都是线性。
- 最低点以下、最高点以上:取端点值保持常数。上面的表最高只给到 600 度,那么 800 度时用的还是 600 度那一行的数, 不会顺着下降趋势继续外推。
第二条是最需要留意的。它的好处是不会外推出负模量这种荒唐结果, 代价是你不会知道自己已经算到表外面去了 —— Abaqus 既不报错也不警告。
另外,插值是在你给的点之间做的,所以点给得太少会把非线性抹平。 钢的模量在 400 到 600 度之间掉得很快,只给 20 和 600 两个点, 中间一大段都会被拉成一条直线,400 度附近的刚度会被明显高估。 这不是软件的问题,是表的问题。
07报错对照
| 报错 | 含义 | 怎么改 |
|---|---|---|
all rows must have the same length | 某一行的列数和别的行不一样 | 通常是漏写了某一行的温度,逐行数一遍 |
the first plastic strain at temperature 400 must be 0 | 塑性表某个温度组的首行塑性应变不是 0 | 每个温度组都要单独从 0 起步 |
plasticStrain at temperature 400 must increase down the table | 组内塑性应变没有递增 | 同一温度的行要挨在一起并按应变排序 |
type LAMINA with temperatureDependency true needs 7 values per row | 声明了温度相关但列数不够 | 补上温度列,或者去掉那句声明 |
type LAMINA needs 6 values per row, or 7 with a trailing temperature column | 列数两种解释都不符合 | 按报错里给的两个数字对一遍 |
"table" is empty | 写了 table 但数组是空的 | 要么填数据,要么整个属性删掉 |
row [...] is not a list of numbers | 某一行里混进了字符串或 null | 常见于从表格复制时带进了空单元格 |
完整的字段清单和更多例子在帮助文档的 JSON 格式一节,导热与比热的温度表写法在导热系数与比热那篇。