在 PyBaMM 里打开热模型只需要一个选项:DFN({"thermal": "lumped"})。仿真照常跑完,出来一条温度曲线,看上去也合情合理。下面这几个问题的共同点是看起来都不像错:一个按构造恒为零的产热变量;四个参数集直接省掉的一整项热源;一个因为几何写法而根本热不起来的电池;以及一个悄悄从 25 °C 开始的”低温”仿真。文中所有数字都是用 PyBaMM 26.5.0,在带热参数的 8 个内置锂离子参数集上实测得到的。
PyBaMM 电池建模系列 · 静默错误实测(第 3 / 7 篇):上一篇 PyBaMM Experiment 跑完了却是错的:五个实测陷阱 · 下一篇 PyBaMM 的容量衰减到底在量什么:80% capacity、Capacity [A.h] 与 Loss of capacity 实测 · 专题页:数据管线 4 篇 + 静默错误实测 7 篇 · RSS 订阅。
一、默认模型是等温的,而且它的产热变量全是零
pybamm.lithium_ion.DFN() 默认 "thermal": "isothermal":电池温度在每个位置、每个时刻都等于环境温度,不解能量方程。这个默认值本身没问题。不那么显然的是产热变量里装的是什么:
| Chen2020,1C 放电 | "Total heating [W]" 峰值 |
|---|---|
DFN() |
每个时间点都是 0.0 W |
DFN({"calculate heat source for isothermal models": "true"}) |
1.04 W |
等温子模型(pybamm/models/submodels/thermal/isothermal.py)里,只要没打开这个选项,欧姆热、不可逆热、可逆热、总产热和表面散热全部被赋成标量 0。变量是存在的,sol["Total heating [W]"] 也返回一个长度正确的数组——只是里面全是零。用默认模型做的”产热分布图”或者”这个工况产多少热”的表,报告的是一个完全不发热的电池。
第二个后果:等温模型完全忽略 "Initial temperature [K]"。它的温度就是环境温度。只把初始温度设成 263.15 K,8 个参数集的 1C 容量和 25 °C 时逐位相同(保留三位小数);只设环境温度,才得到完整的低温结果。
二、等温和集总热模型之间不是”小修正”
很容易把集总(lumped)模型当成把答案轻轻推一下的精化。下面是两种模型下的 1C 和 3C 放电:
| 参数集 | 1C:等温 → 集总 | 温升 | 3C:等温 → 集总 | 温升 |
|---|---|---|---|---|
| Chen2020 | 4.992 → 5.001 A·h(+0.2%) | 13.8 K | 2.326 → 2.418 A·h(+4.0%) | 58.0 K |
| OKane2022 | 4.955 → 5.005 A·h(+1.0%) | 12.9 K | 2.333 → 5.000 A·h(+114%) | 49.6 K |
| ORegan2022 | 4.422 → 4.736 A·h(+7.1%) | 15.6 K | 1.110 → 3.506 A·h(+216%) | 43.3 K |
| Ai2020 | 2.413 → 2.414 A·h(0.0%) | 3.6 K | 2.308 → 2.319 A·h(+0.5%) | 13.8 K |
| Mohtat2020 | 4.836 → 4.852 A·h(+0.3%) | 3.0 K | 4.589 → 4.713 A·h(+2.7%) | 9.3 K |
| Marquis2019 | 0.854 → 0.854 A·h(0.0%) | 0.4 K | 0.821 → 0.823 A·h(+0.2%) | 1.2 K |
| Ecker2015 | 0.170 → 0.170 A·h(0.0%) | 0.1 K | 0.168 → 0.168 A·h(+0.1%) | 0.6 K |
| NCA_Kim2011 | 0.476 → 0.476 A·h(0.0%) | 0.0 K | 0.461 → 0.461 A·h(0.0%) | 0.1 K |
这张表里其实混着三件事,下面各用一节展开。
- 三个 LG M50 参数集在 3C 下被集总模型加热了 43–58 K,但这件事有没有影响取决于电化学部分。OKane2022 和 ORegan2022 随着升温分别多放出 114% 和 216%。Chen2020 升温 58 K,容量只多 4%,因为它的电解液和颗粒输运参数都不随温度变(见参数集那篇里的温度表)。热模型在跑,电化学几乎不理它。
- 温升有多大,由一个没人为你的测试台测过的换热系数决定(第三节)。
- 有四个参数集几乎完全热不起来,原因和化学体系毫无关系(第四节)。
两个模型都谈不上”正确”。等温等于完美散热——电池夹在一块很大的热沉上;默认换热系数下的集总模型大致相当于电池放在静止空气里。选跟你要复现的测试条件一致的那个,并且知道在高倍率下两者可以差三倍。
三、一个没测过的数决定了高倍率的答案
集总模型通过 "Total heat transfer coefficient [W.m-2.K-1]" 乘以 "Cell cooling surface area [m2]" 散热。内置参数集的默认值是 10(Chen2020、OKane2022、ORegan2022、Marquis2019、Ecker2015)、5(Mohtat2020)、25(NCA_Kim2011)或 35(Ai2020)。在 OKane2022 上以 3C 扫这个系数:
| 换热系数 | 温升 | 3C 容量 |
|---|---|---|
| 等温(无穷大) | 0 K | 2.333 A·h |
| 1000 W/m²·K | 1.9 K | 2.598 A·h |
| 100 W/m²·K | 15.1 K | 4.647 A·h |
| 25 W/m²·K | 31.8 K | 4.934 A·h |
| 10 W/m²·K(默认) | 49.6 K | 5.000 A·h |
| 5 W/m²·K | 62.3 K | 5.025 A·h |
| 1 W/m²·K | 78.2 K | 5.047 A·h |
仅仅一个边界条件,就让 3C 容量在 2.3 到 5.0 A·h 之间变动。再看默认那一行实际在说什么:电池在 3C 下放出满容量,是因为它的温度峰值接近 75 °C。用这个模型得出的”3C 没问题”,说的是一颗很烫的电池——连同它对老化和安全意味着的一切——而不是室温下的电池。
换热系数不是电芯的属性,它描述的是夹具、气流和相邻电芯。要和实测对比,这个数就必须来自你的测试条件:在壳体上贴一个热电偶,记录一次已知热脉冲后的冷却曲线,就足以拟合出来。不能直接用参数集里的值。
四、八个参数集里有四个描述的是”一张两面散热的极片”
集总电池能不能热起来,由热时间常数决定:τ = 热容 ÷(h × 散热面积)。逐个参数集算出来:
| 参数集 | 散热面积 ÷ 体积 | 热容 | h | τ | 3C 温升 |
|---|---|---|---|---|---|
| NCA_Kim2011 | 12,143 m⁻¹ | 9.4 J/K | 25 | 7 s | 0.1 K |
| Ecker2015 | 11,316 m⁻¹ | 4.2 J/K | 10 | 24 s | 0.6 K |
| Marquis2019 | 7,295 m⁻¹ | 14.1 J/K | 10 | 25 s | 1.2 K |
| Mohtat2020 | 10,459 m⁻¹ | 121.1 J/K | 5 | 59 s | 9.3 K |
| Ai2020 | 394 m⁻¹ | 41.3 J/K | 35 | 195 s | 13.8 K |
| Chen2020、OKane2022 | 219 m⁻¹ | 42.8 J/K | 10 | 806 s | 58.0 / 49.6 K |
| ORegan2022 | 219 m⁻¹ | 60.6 J/K | 10 | 1141 s | 43.3 K |
前四个很显眼。它们的 "Cell cooling surface area [m2]" 都等于电极高度 × 电极宽度 × 2(误差 0.5% 以内),"Cell volume [m3]" 等于建模的那一层电极叠层的体积。换句话说,这里的”电池”就是一张极片,两个面都在散热。这种几何散热快到集总温度在几秒到一分钟内就跟上环境温度。把这四个参数集切到 "lumped" 几乎什么都不变——不是热模型没生效,而是它描述的这个”电池”根本存不住热。Mohtat2020 在 3C 下还能升 9.3 K,只是因为它的可逆热异常大(下一节)。
相比之下,LG M50 的几个参数集描述的是一个真实的 21700 钢壳:0.00531 m² 正好是直径 21 mm、高 70 mm 圆柱的侧面加两个端面,电极叠层占壳体体积的 85%。如果你用前四个参数集之一去模拟一颗封装好的电池,在相信任何温度之前,先把几何换成真实的壳体或软包尺寸。
五、四个参数集没有可逆热
电池产热主要有三部分:电解液和固相里的欧姆热、反应过电位带来的不可逆热,以及可逆热(熵热)。可逆热正比于开路电位对温度的导数(Bernardi、Pawlikowski、Newman,1985)。PyBaMM 里这个导数是 "… electrode OCP entropic change [V.K-1]"。Chen2020、OKane2022、Ecker2015 和 NCA_Kim2011 里,它对正负两极都恰好是 0.0。仿真在整整一项热源被关掉的情况下照常运行,没有任何提示。
在确实包含这项的四个参数集里,它有多重要(集总模型,可逆热净值占总产热的比例):
| 参数集 | C/5 | 1C | 3C |
|---|---|---|---|
| Mohtat2020 | 96.4% | 85.7% | 73.6% |
| Ai2020 | 78.5% | 46.8% | 30.7% |
| ORegan2022 | 28.9% | 19.3% | 26.8% |
| Marquis2019 | 20.8% | 5.5% | 2.8% |
| Chen2020、OKane2022、Ecker2015、NCA_Kim2011 | 按构造为 0% | ||
在同样这四个参数集里,把它去掉对预测温升的影响:
| 参数集 | C/5 温升:原始 → 熵系数置零 | 1C 温升:原始 → 熵系数置零 |
|---|---|---|
| ORegan2022 | 2.46 → 0.80 K(−68%) | 15.6 → 11.0 K(−30%) |
| Ai2020 | 0.53 → 0.13 K(−75%) | 3.58 → 1.70 K(−53%) |
| Mohtat2020 | 0.63 → 0.02 K(−97%) | 3.04 → 0.25 K(−92%) |
| Marquis2019 | 0.069 → 0.011 K(−85%) | 0.37 → 0.16 K(−56%) |
规律和预期一致:可逆热随电流线性增长,不可逆热和欧姆热大致随电流平方增长,所以缺掉的这一项在低倍率下影响最大——恰恰是慢速循环、工况平均和日历+循环老化研究所在的区间。参数集之间的差距(1C 下从 6% 到 86%)本身也是一个警告:熵系数随化学体系和荷电状态而变,从别的参数集借一个过来,并不比留成零好多少。
LG M50 是唯一能直接对照的电芯。Chen2020 和 OKane2022 描述它时用的是零熵系数,正负极和隔膜的比热都是 700 J/kg·K;ORegan2022 则带着同一颗电芯的实测热参数(O’Regan 等,2022),包括熵系数和大 42% 的热容(60.6 对 42.8 J/K)。如果你需要 LG M50 的温度,应该从 ORegan2022 开始。
六、从 25 °C 开始的”低温启动”
这是代价最高的一个。要模拟低温放电,最自然的写法是:
pv.update({"Ambient temperature [K]": 253.15})
在等温模型里这是对的。在集总模型里不对:电池温度从 "Initial temperature [K]" 出发——所有内置参数集里都是 298.15 K——然后按第四节的时间常数向寒冷的环境温度弛豫。对 LG M50 来说这需要 13 到 19 分钟,差不多就是一次 3C 放电的时长。于是仿真里的电池大部分时间是在温热状态下干活的。
| 集总模型,放电到截止电压 | 只设环境温度(电池从 25 °C 开始) | 环境温度和初始温度都设 |
|---|---|---|
| OKane2022,−20 °C,3C | 19.7 分钟放出 4.932 A·h | 1.1 分钟放出 0.275 A·h |
| ORegan2022,−10 °C,3C | 12.7 分钟放出 3.170 A·h | 0.9 分钟放出 0.232 A·h |
| ORegan2022,−20 °C,2C | 13.2 分钟放出 2.207 A·h | 1.3 分钟放出 0.212 A·h |
| ORegan2022,−20 °C,3C | 12.3 分钟放出 3.082 A·h | 0.5 分钟放出 0.125 A·h |
真正冷的电池一分钟之内就碰到截止电压,自发热还来不及救它。同一个仿真只少设一个参数,报告的放电量就多出 10 到 25 倍,得出一颗”−20 °C 下扛得住 3C”的电池。
如果电池熬过了第一分钟,两种写法的最终容量几乎一样——到放电末期自发热已经占主导,容量是在那时决定的。误差转移到了功率预测上:
| 集总模型,1C | 10 s 时电压(从 25 °C 开始) | 10 s 时电压(从低温开始) | 容量(两种) |
|---|---|---|---|
| OKane2022,−10 °C | 4.006 V | 3.886 V | 4.868 A·h |
| Mohtat2020,−20 °C | 4.105 V | 3.917 V | 2.909 / 2.906 A·h |
| ORegan2022,−20 °C | 4.108 V | 3.888 V | 3.414 / 3.384 A·h |
头几秒电压偏乐观 0.12–0.22 V,而这恰恰是低温启动或功率能力研究要的那个量。
如果按 Experiment 接口的本意去用,它处理得比直接改参数好。在 26.5 里,第一个步骤的温度会被复制进 "Initial temperature [K]"(见 simulation.py 的 _set_up_and_parameterise_experiment)。所以下面两种写法都会让电池从低温开始,而且都复现了上面 0.275 A·h 的结果:
step = pybamm.step.string("Discharge at 3C until 2.5 V", temperature="-20oC")
experiment = pybamm.Experiment([step])
experiment = pybamm.Experiment(["Discharge at 3C until 2.5 V"], temperature=253.15)
把温度写进字符串里——"Discharge at 3C until 2.5 V at -20oC"——会抛出 ValueError: Temperature must be specified as a keyword argument instead of in the string,至少是大声地失败。静默的是前面那种:在 ParameterValues 里改了环境温度,却没动初始温度。
七、每次热仿真之后跑一遍的检查
下面这个函数接收一个已经求解过的 pybamm.Simulation,对上面每一种”能跑完但会误导”的设置给出警告:
import numpy as np
import pybamm
def thermal_audit(sim):
"""Warnings for a solved pybamm.Simulation whose thermal set-up runs but misleads."""
opts, pv, sol = sim.model.options, sim.parameter_values, sim.solution
out = []
if opts["thermal"] == "isothermal":
if opts["calculate heat source for isothermal models"] == "false":
out.append("isothermal: every heating variable is 0 unless "
"'calculate heat source for isothermal models' is 'true'")
return out
def first(name):
return float(np.ravel(sol[name].entries)[0])
T0 = first("Volume-averaged cell temperature [K]")
T_amb = first("Volume-averaged ambient temperature [K]")
if abs(T0 - T_amb) > 0.5:
out.append(f"cell starts at {T0 - 273.15:.1f} °C but ambient is "
f"{T_amb - 273.15:.1f} °C: set 'Initial temperature [K]' too")
for electrode in ("Negative", "Positive"):
dUdT = pv[f"{electrode} electrode OCP entropic change [V.K-1]"]
if isinstance(dUdT, (int, float)) and dUdT == 0:
out.append(f"{electrode.lower()} electrode entropic change is 0: "
"no reversible heat from it")
heat_capacity = (first("Volume-averaged effective heat capacity [J.K-1.m-3]")
* pv["Cell volume [m3]"])
tau = heat_capacity / (pv["Total heat transfer coefficient [W.m-2.K-1]"]
* pv["Cell cooling surface area [m2]"])
if tau < 120:
out.append(f"thermal time constant is {tau:.0f} s: "
"this lumped cell behaves almost isothermally")
return out
在各种配置下跑一次 1C 放电的输出:
Chen2020, default DFN
isothermal: every heating variable is 0 unless 'calculate heat source for isothermal models' is 'true'
Chen2020, isothermal + heat source
(no warnings)
Chen2020, lumped
negative electrode entropic change is 0: no reversible heat from it
positive electrode entropic change is 0: no reversible heat from it
OKane2022, lumped, only ambient -20 C
cell starts at 25.0 °C but ambient is -20.0 °C: set 'Initial temperature [K]' too
negative electrode entropic change is 0: no reversible heat from it
positive electrode entropic change is 0: no reversible heat from it
OKane2022, lumped, step temperature -20 C
negative electrode entropic change is 0: no reversible heat from it
positive electrode entropic change is 0: no reversible heat from it
Marquis2019, lumped
thermal time constant is 25 s: this lumped cell behaves almost isothermally
ORegan2022, lumped, both -10 C
(no warnings)
Ai2020, lumped
(no warnings)
它查不了的:换热系数是否符合你的测试台(第三节),以及电化学部分是否响应给它的温度(第二节的 Chen2020)。这两件都需要和实测对比,代码检查做不到。熵系数检查只标出常数零;如果参数集给的是一个函数,就默认它是认真给的。
八、测量方法
- PyBaMM 26.5.0,Python 3.13,Apple M3,默认
IDAKLUSolver。模型为pybamm.lithium_ion.DFN,选项{"thermal": "isothermal"}或{"thermal": "lumped"}。 - 每次放电从
initial_soc=1.0开始,通过Experiment放到参数集自己的Lower voltage cut-off [V]。 - 温升取
"Volume-averaged cell temperature [K]"的最大值减去初值。产热量是"Total heating [W]"及其可逆、不可逆、欧姆分量在解的时间点上用梯形法做的时间积分。 - τ 用 t = 0 时的
"Volume-averaged effective heat capacity [J.K-1.m-3]"乘以"Cell volume [m3]",除以 h 乘散热面积——和集总子模型用的是同一组量(lumped.py、base_thermal.py)。 - “熵系数置零”只把两个 entropic change 参数设为 0,其余不动。
- 这 8 个参数集是定义了集总热参数的全部内置锂离子参数集。Prada2013 和 Ramadass2004 在集总模式下会抛
KeyError(分别缺集流体厚度和电池体积);那是大声的失败,本文不涉及。 - 每个参数集在独立进程里带超时运行,没有一个卡住。
References
- D. Bernardi, E. Pawlikowski, J. Newman, A General Energy Balance for Battery Systems, J. Electrochem. Soc. 132 (1985) 5–12.
- R. Timms, S. G. Marquis, V. Sulzer, C. P. Please, S. J. Chapman, Asymptotic Reduction of a Lithium-Ion Pouch Cell Model, SIAM J. Appl. Math. 81 (2021) 765–788.
- K. O’Regan, F. Brosa Planella, W. D. Widanage, E. Kendrick, Thermal-electrochemical parameters of a high energy lithium-ion cylindrical battery, Electrochimica Acta 425 (2022) 140700.
- C.-H. Chen 等, Development of Experimental Techniques for Parameterization of Multi-scale Lithium-ion Battery Models, J. Electrochem. Soc. (2020).
- S. E. J. O’Kane 等, Lithium-ion battery degradation: how to model it, Phys. Chem. Chem. Phys. (2022).
- PyBaMM:热模型与热子模型 API
相关阅读:PyBaMM 18 个内置参数集实测——为什么 Chen2020 几乎不响应温度;PyBaMM Experiment 常见陷阱——实验正常跑完却交回错误结果的其他方式;PyBaMM 求解器收敛失败排查——低温高倍率跑不完的时候;温度如何进入 SEI 增长和析锂,见 PyBaMM SEI 与析锂实测。
