工程师平台
Abaqus 实战2026-09-06

凭空冒出来的热应力,八成不是参考温度的错

「模型里凭空出现热应力」几乎总是被归咎于零应变参考温度填错了。 但把 Abaqus 的热应变表达式写出来会发现:膨胀系数是常数时,这个参考温度会完全抵消,填多少都一样。 这篇先把它推一遍,再说清楚 ZERO 到底什么时候有用、 凭空热应力真正的来源是什么。
常数 α:ZERO 无效
代进表达式两项相减,参考温度整个消掉,只剩 α·(T − T初始)。 填 0、填 20、填 293,结果完全相同。
ZERO 只在 α 是温度表时才起作用
那时两项里的 α 取值不同,抵消不掉。差多少取决于 α 随温度变化的幅度, 第 03 节有算例。
凭空热应力的真凶是初始温度场
没定义初始温度,Abaqus 按 0 处理。再给个 20 °C 的「室温」场, 模型就认为温度升了 20 度 —— 应力是真算出来的,不是 bug。

01先把表达式写出来

Abaqus 里一点的热应变不是简单的 α·ΔT,它带一个把初始状态扣掉的项:

ε_th = α(T) · (T − T⁰)  −  α(Tᴵ) · (Tᴵ − T⁰)

  T    当前温度
  Tᴵ   该点的初始温度(*INITIAL CONDITIONS, TYPE=TEMPERATURE)
  T⁰   零应变参考温度(*EXPANSION 的 ZERO,插件里的 zeroTemperature)
  α    膨胀系数,可以是常数,也可以是温度的函数

三个温度各管各的事,很多混乱来自把它们当成一回事:

是什么在哪里定义
T0材料属性的一部分:α 是以哪个温度为基准标定的材料里,Expansionzero
TI模型状态:分析开始时这个点多少度载荷模块的 Predefined Field,Initial 步
T模型状态:当前增量步这个点多少度后续步里的温度场,或者传热分析算出来的
T⁰ 属于材料,Tᴵ 和 T 属于模型。同一个数字出现在这三处不代表它们是同一件事。
第二项存在的理由
如果没有这个减法,一个初始就处在 20 °C、参考温度是 0 的模型, 在第一个增量步还没加任何载荷时就已经带着 α×20 的应变了 —— 分析从一个自带内应力的状态开始。 加上这一项之后,T = Tᴵ 时热应变恒为 0, 分析总是从无应力状态起步。这是想要的行为。

02常数 α:参考温度完全抵消

把 α 当常数(也就是 JSON 里只给一个 alpha 值、 不给温度表),两项里的 α 是同一个数,直接提出来:

ε_th = α · (T − T⁰) − α · (Tᴵ − T⁰)

     = α·T − α·T⁰ − α·Tᴵ + α·T⁰
              └────┬────┘
                 抵消

     = α · (T − Tᴵ)

T⁰ 不见了。 剩下的式子里只有当前温度和初始温度之差, 这正是直觉里的 α·ΔT。

所以,如果你的 α 是个常数
zeroTemperature 填 0、填 20、填 293,甚至完全不填, 算出来的热应变一模一样。 改这个值去调试凭空热应力,是在改一个不参与计算的量。

这一条值得自己验一遍,成本很低:建一个单元、给一组约束、 用常数 α 跑两次,一次 zero 填 0、一次填 100, 对比应力云图。两次结果应当完全相同。

03那 ZERO 什么时候有用:α 随温度变的时候

α 给成温度表之后,表达式里两项的 α 取值不同 —— 一个是 α(T),一个是 α(Tᴵ) —— 就提不出来了,T⁰ 留在式子里:

ε_th = α(T) · (T − T⁰)  −  α(Tᴵ) · (Tᴵ − T⁰)
        ↑                      ↑
      不同的两个值,抵消不掉

一个算例

设初始温度 TI = 20,当前温度 T = 400, 膨胀系数取 α(20) = 1.2×10−5、α(400) = 1.4×10−5

这两个 α 是为了演算编的示意值
1.2e-5 那个数来自插件示例库里 Steel_Q345alpha(演示值);1.4e-5 是我为了让这个算例有两个不同的 α 而假设的示意值,不代表任何材料在 400 °C 的真实膨胀系数。 这一节要说明的是「差多少」这个结构,不是这两个数本身。
T⁰ 取值第一项 α(T)(T − T⁰)第二项 α(Tᴵ)(Tᴵ − T⁰)ε_th
201.4e-5 × 380 = 5.320e-31.2e-5 × 0 = 05.320e-3
01.4e-5 × 400 = 5.600e-31.2e-5 × 20 = 2.400e-45.360e-3
两者相差 4.0e-5,约 0.75%。α 随温度变化越大、T⁰ 与 Tᴵ 离得越远,这个差就越大。

0.75% 的应变差,在一个受约束的构件里换算成应力是 E 乘这个差 —— 不算大,但也不是舍入噪声。结论是:α 给成表时,T⁰ 必须填成 α 标定时用的那个基准温度, 不能随手填 0。这个基准温度应当和 α 数据一起来源, 两者分开就没法用了。

04凭空热应力:真正的来源

既然常数 α 时 T⁰ 不参与,那第一个增量步就冒出来的热应力是哪来的? 回到那个式子 —— 它只剩 α·(T − Tᴵ)。 要让它非零,只能是 T 和 Tᴵ 不相等

来源一:初始温度场压根没定义(最常见)

没有 *INITIAL CONDITIONS, TYPE=TEMPERATURE 时, Abaqus 认为 TI = 0。这时你在第一个分析步里给一个 「室温 20 °C」的温度场 —— 你以为什么都没变, 模型认为温度升了 20 度,于是老老实实算出了对应的热应变。 应力是真的,逻辑也是对的,错的是那个没写的初始条件。

症状
第一个增量步结束,还没加任何机械载荷,应力云图上已经有一片非零。 量级检查一下:如果它接近 E × α × 20(或者 E × α × 你那个「室温」的值), 那就是这个原因。

来源二:温度场只给了一部分区域

装配体里一部分零件有温度场、一部分没有,没有的那部分按 0 处理。 两边一接触,界面上就是一个几百度的虚假温差, 接触面附近会出现一圈量级离谱的应力。

来源三:温标不统一

初始条件按摄氏给了 20,后续温度场按开氏给了 293。 模型看到的是温度从 20 升到 293,涨了 273 度。这一类见下一节。

排查顺序
  1. 先确认 α 是常数还是表。是常数就不要动 ZERO, 它不参与。
  2. 查 Initial 步里有没有温度 Predefined Field,覆盖范围是不是全模型。
  3. 查初始温度场和后续温度场的数值是不是同一个标度。
  4. 以上都对,α 又是表,这时才回头看 T⁰ 填的是不是 α 的标定基准。

05摄氏还是开氏:示例库里两种都有

插件示例库 materials_sample.json 里有两条带zeroTemperature 的材料,它们用的不是同一个温标

示例库条目alphazeroTemperature看起来是
Steel_Q3451.2e-0520.0摄氏
Al_6061_T62.36e-05293.0开氏
Steel_S355_TempDep1.2e-0520.0摄氏
插件示例库中的演示值,用于说明 JSON 字段的写法,不构成材料性能数据。这三条同处一个文件,温标并不统一——把它们导进同一个模型正是本节要讲的那种错误。

这不是文件写错了,示例库的目的是演示各种写法。 但它恰好演示了一个真实的坑:同一个模型里三个温度必须同标度。 材料的 T⁰ 用开氏、模型的温度场用摄氏,那个 273 的偏移会直接进结果。

什么时候两种都行,什么时候必须开氏

  • 只涉及温差的分析(纯热膨胀、导热), 摄氏和开氏等价 —— 温差的数值一样,α 的数值也一样 (α 的单位是「每度」,一个摄氏度和一个开尔文是同样大的间隔)。 统一即可。
  • 出现绝对温度的地方必须开氏:辐射换热(正比于 T⁴)、 Johnson-Cook 里的同调温度。这些式子里 T 本身进运算, 填 20 和填 293 不是一回事。
α 的数值不随温标变
这一点常被绕进去:α 是「每升高一度的相对伸长」, 而一摄氏度和一开尔文是同样大的温度间隔, 所以 1.2e-5 在两种温标下是同一个值,不需要换算。 要换的是温度本身那几个数,不是 α。
单位制层面的十项对照见单位制那篇的第 05 节

06JSON 里怎么写:一个裸数字写法的坑

expansion 是单列属性(只有 alpha 一列), 所以它和密度一样允许裸数字。但这里有个别处没有的后果:

"thermal": {
  "expansion": 1.2e-5                 ← 合法,但没有地方放 zeroTemperature
}

"thermal": {
  "expansion": {
    "alpha": 1.2e-5,
    "zeroTemperature": 20.0           ← 只有对象写法才带得上
  }
}
裸数字写法会静默丢掉 ZERO
插件读选项(typezeroTemperature)的方式是: 这一块是对象就读它的键,不是对象就当没有选项。 所以写成裸数字时,你没法附带参考温度,也不会有任何提示 ——Expansion 会以 Abaqus 的默认参考温度建出来。
好消息是,按第 02 节的推导,α 是常数时这个差别不影响结果。 真正需要 ZERO 的场合(α 给成表)本来就得用对象写法, 因为表要写在 table 键里。

温度相关的 α

"expansion": {
  "table": [
    [1.2e-5,  20.0],
    [1.3e-5, 200.0],
    [1.4e-5, 400.0]
  ],
  "zeroTemperature": 20.0
}

规则和别的属性一致:膨胀本身要一列,行有两列就意味着第二列是温度。 上面这组 α 是为了演示表格写法编的示意值, 不是任何材料的实测数据 —— 真要用,α 和它的标定基准温度必须一起来自同一份可核对的数据源。

负的 α 不会被拦

插件对好几列做了「必须为正」或「必须非负」的检查(模量、屈服应力、 热导率、比热、密度),但 alpha 这一列没有。 这是有意的:负热膨胀材料真实存在,受热收缩是合法的物理行为。 所以 α 填成负数不会有任何提示,得自己确认那是不是笔误。

报错触发条件改法
thermal.expansion: missing key(s) alpha对象写法里没有 alpha 键补上 alpha,或者改成裸数字写法
thermal.expansion: values must be numbers值是字符串去掉引号;从 Excel 导出的 JSON 最容易带引号
thermal.expansion: all rows must have the same lengthtable 里有的行带温度列有的不带要么全部一列,要么全部两列
thermal.expansion: "table" is emptytable 键在但是空数组补数据,或者整块删掉
unknown Abaqus constant "ORTHO"type 拼错了名字要和 Abaqus 常量一致,插件会先转成大写再找
逐字取自插件 1.2.1 的 materialImporterKernel.py,前缀 thermal.expansion 是该块在报错里的标签。完整 22 条见帮助文档第 08 节。

JSON 各字段的完整定义在帮助文档第 05 节,报错对照表在第 08 节。同一个 thermal 块里另外两项(热导率、比热) 的单位换算见单位对照表—— 那两项一个数值不变、一个要乘 106, 是热分析里最容易一起搞错的一组。瞬态传热还要用到密度,见密度那篇的第 04 节

常见问题

Abaqus 的零应变参考温度 ZERO 到底起什么作用?

它是材料属性的一部分,表示膨胀系数是以哪个温度为基准标定的。但要注意:Abaqus 的热应变表达式是 α(T)(T − T⁰) 减去 α(Tᴵ)(Tᴵ − T⁰),当膨胀系数是常数时,把 α 提出来后 T⁰ 会完全抵消,只剩下 α 乘以当前温度与初始温度之差。也就是说常数 α 的情况下 ZERO 填多少都一样,改它去调试热应力是在改一个不参与计算的量。只有当 α 给成随温度变化的表时,两项里的 α 取值不同、抵消不掉,ZERO 才真正影响结果。

Abaqus 里凭空出现热应力是什么原因?

最常见的原因不是参考温度填错,而是初始温度场没有定义。没有初始条件时 Abaqus 认为初始温度是 0,你在第一个分析步里给一个 20 度的室温场,模型就认为温度升了 20 度,于是算出了对应的热应变,应力是真实算出来的。判断方法是看第一个增量步结束时的应力量级是不是接近弹性模量乘膨胀系数再乘那个室温值。第二个常见原因是温度场只覆盖了装配体的一部分,没覆盖的零件按 0 处理,界面上出现虚假温差。第三个是初始温度用摄氏、后续温度场用开氏。

热膨胀系数用摄氏还是开氏,数值要换算吗?

膨胀系数本身不需要换算。α 的含义是每升高一度的相对伸长,而一摄氏度和一开尔文是同样大的温度间隔,所以同一个 α 在两种温标下是同一个数值。需要统一的是温度本身那几个数:初始温度、当前温度场、材料的参考温度必须在同一个标度上。只涉及温差的分析两种温标等价,统一即可;但出现绝对温度的地方必须用开氏,比如辐射换热正比于温度的四次方,以及 Johnson-Cook 本构里的同调温度。

插件的 JSON 里 expansion 写成一个数字可以吗?

可以,膨胀是单列属性,写成 "expansion": 1.2e-5 是合法的。但有个后果:插件读取 type 和 zeroTemperature 这类选项时,只在这一块是对象的情况下去读,写成裸数字就当作没有选项,参考温度会被静默丢掉,Expansion 以 Abaqus 的默认参考温度建出来。好在按前面的推导,常数 α 时参考温度不影响结果;真正需要它的场合是 α 给成温度表,而那时本来就必须用对象写法,因为表要放在 table 键里。

Abaqus 膨胀系数可以是负数吗,插件会拦吗?

可以是负数,插件不拦。插件对弹性模量、屈服应力、热导率、比热做了必须为正的检查,对密度做了必须非负的检查,但膨胀系数这一列没有任何符号检查。这是有意的,负热膨胀材料真实存在,受热收缩是合法的物理行为。代价是填反了符号不会有任何提示,需要自己确认那不是笔误——症状通常是升温工况里构件往内缩、约束处的应力符号与预期相反。

温度相关的热膨胀系数怎么填,参考温度还要填吗?

用 table 写法,每行是 [膨胀系数, 温度] 两列,同时给出 zeroTemperature。这种情况下参考温度必须填,而且要填成这组 α 数据标定时所用的基准温度,不能随手填 0——因为 α 随温度变化时表达式里的两个 α 取值不同,参考温度不再抵消。差多少取决于 α 的变化幅度以及参考温度与初始温度的距离。实际操作上,α 表和它的基准温度应当来自同一份数据源,两者分开就没法正确使用。

这一步可以不自己做

参考温度只有在 α 给成温度表时才影响结果,而那时它必须跟着 α 一起来。 插件把 zeroTemperature 和 α 表存在同一条材料里,两者不会在传抄中走散。

在线材料库需要 Abaqus 2023 或更高版本;2022 及更早只能用本地 JSON 材料库。