Skip to content

气液闪蒸计算组件 (Flash) 代码解析

flash.py 是模拟热解过程中焦油(Tar)与气体(Gas)相平衡的核心组件。该代码通过 Rachford-Rice 算法 求解气化分率,并针对高性能计算环境进行了深度优化。


代码采用了 Numba 的编译技术,将 Python 函数转化为高性能机器码,特别关注了数组操作的效率。

@njit(cache=True)
def flash(...):
  • @njit: 强制使用无 Python 对象的原生模式(No-python mode),确保计算速度接近 C 语言。
  • cache=True: 首次编译后将机器码持久化至磁盘,避免 Web 服务重启后的冷启动耗时。

为了解决前端传入数据或 NumPy 矩阵可能出现的 (N,)(N, 1) 形状不一致问题,代码通过显式检测 ndim 来提取标量,这是保证 Numba 稳定运行的关键:

# 核心逻辑:确保无论输入是 1D 还是 2D 数组,均能正确提取标量
val_mt = mt[i] if mt.ndim == 1 else mt[i, 0]
val_ft = ft[i] if ft.ndim == 1 else ft[i, 0]

为了避免在循环中重复申请内存,代码在函数开始处预分配了固定长度的局部 NumPy 数组:

  • f: 包含气体项(索引 0)和单体项(索引 1~nmax)的总摩尔通量。
  • xmw: 各组分对应的分子量数组。
  • k: 气液分配系数。

2. 数值迭代:割线法 (Secant Method)

Section titled “2. 数值迭代:割线法 (Secant Method)”

代码通过改进的割线法求解 Rachford-Rice 方程。相比传统的牛顿法,它无需计算导数,更适合复杂的蒸气压关联式。

# 割线法迭代逻辑
for _ in range(100):
f2 = 0.0
for ii in range(nmax + 1):
km1 = k[ii] - 1.0
f2 += z[ii] * km1 / (km1 * x2 + 1.0) # 方程主体
# 计算下一个迭代点 x3
x3 = x2 - f2 * (x2 - x1) / denom

由于热解计算可能涉及极端物理条件,代码实现了多重“防崩溃”保护:

迭代过程中,气化分率 必须严格处于 区间。代码通过硬编码边界防止数值发散:

if x3 > 1.0: x3 = 0.999999
if x3 < 0.0: x3 = 1e-6
  • denom_mw: 若分子量接近 0,强制设为 1e-18,防止计算摩尔分率时溢出。
  • Ftot: 若总物流量低于 1e-8,直接跳过计算返回初始态,避免对极小噪声数据进行无效迭代。
  • inv_sumx: 归一化前检查总和,防止出现 Inf

该函数不仅返回计算结果,还会就地修改 (In-place Modify) 传入的数组引用,以实现最高性能:

数组变量修改逻辑目的
ftoldftold[i] = val_ft更新上一时刻的质量分布快照
metoldmetold[idx] = xi更新凝聚相(液相)中的单体残留量
taroldtarold[idx] += yi累加各分子量段的气相(焦油)产率