8.4 KiB
1. 模型定位
gas_cylinder.py 实现的是高压气瓶的 0D 集总参数模型 HighPressureGasCylinder。模型只描述气瓶内部平均热力状态,不解析气瓶内的轴向、径向或局部流场分布。
主要假设:
- 气瓶有效容积
V固定。 - 气瓶内工质均匀,使用单一平均密度和单一平均比内能描述。
- 独立守恒状态只有总质量
mass和总内能U。 - 压力、温度和比焓通过 CoolProp 由当前守恒状态恢复。
- 模型不自行计算边界流量;外部模型给出质量流率和能量流率后,气瓶只更新守恒量。
对应代码:src/cylinder/gas_cylinder.py:20-142
2. 参数与状态
默认参数定义在 src/cylinder/gas_cylinder.py:14-17:
| 参数 | 默认值 | 含义 |
|---|---|---|
DEFAULT_FLUID |
Helium |
CoolProp 工质名称 |
DEFAULT_P_INIT |
18.031e6 Pa |
初始绝对压力 |
DEFAULT_VOLUME |
20e-3 m^3 |
气瓶容积,20 L |
DEFAULT_T_INIT |
78.0 K |
初始温度 |
构造函数输入为:
\left(\mathrm{fluid},\ P_0,\ V,\ T_0,\ \mathrm{backend}\right)
其中 backend 默认是 HEOS。构造函数会检查:
\mathrm{fluid}\ne\varnothing,\quad P_0>0,\quad V>0,\quad T_0>0
气瓶模型的独立状态向量为:
\mathbf{y}_{\mathrm{cyl}}=\left[m_{\mathrm{cyl}},\ U_{\mathrm{cyl}}\right]
其中:
mass对应 $m_{\mathrm{cyl}}$,单位 kg。U对应 $U_{\mathrm{cyl}}$,单位 J。- 压力
P、温度T、密度rho、比内能specific_internal_energy和比焓h都是由这两个守恒量派生出来的量。
3. 初始状态计算
初始化发生在 src/cylinder/gas_cylinder.py:51-56。计算流程如下。
第一步,建立 CoolProp 状态对象:
self._state = AbstractState(backend, fluid)
第二步,用初始压力和初始温度更新热力状态:
self._state.update(CP.PT_INPUTS, P_init, T_init)
对应数学表达为:
\mathrm{state}_0=\mathrm{CoolProp}\left(P_0,T_0,\mathrm{fluid},\mathrm{backend}\right)
第三步,从 CoolProp 读取初始密度:
\rho_0=\rho\left(P_0,T_0\right)
代码中对应:
rho = self._state.rhomass()
第四步,由固定容积计算气瓶初始总质量:
m_{\mathrm{cyl},0}=\rho_0 V
代码中对应:
self.mass = rho * V
第五步,从 CoolProp 读取初始比内能,并计算总内能:
U_{\mathrm{cyl},0}=m_{\mathrm{cyl},0}u_0
其中:
u_0=u\left(P_0,T_0\right)
代码中对应:
self.U = self.mass * self._state.umass()
因此,模型初始化后不再单独保存初始压力和初始温度;后续压力和温度都通过当前 mass、U 和 V 重新计算。
4. 状态恢复计算
运行过程中,模型每次需要热力性质时都会调用 _update_state(),代码位置为 src/cylinder/gas_cylinder.py:58-62。
4.1 密度
气瓶体积固定,因此当前平均密度为:
\rho_{\mathrm{cyl}}=\frac{m_{\mathrm{cyl}}}{V}
代码位置:src/cylinder/gas_cylinder.py:64-67
4.2 比内能
当前比内能由总内能除以总质量得到:
u_{\mathrm{cyl}}=\frac{U_{\mathrm{cyl}}}{m_{\mathrm{cyl}}}
代码位置:src/cylinder/gas_cylinder.py:69-72
这一步要求 mass > 0。apply_flux() 在每次通量更新后会检查质量不能为非正值。
4.3 CoolProp 输入对
模型用质量密度和质量比内能作为 CoolProp 输入对:
self._state.update(CP.DmassUmass_INPUTS, rho, u)
对应数学表达为:
\mathrm{state}=\mathrm{CoolProp}\left(\rho_{\mathrm{cyl}},u_{\mathrm{cyl}}\right)
这里的关键点是:P 和 T 不是独立积分变量,而是 CoolProp 根据 (\rho,u) 反算出来的热力结果。
4.4 压力、温度和比焓
状态恢复后,模型提供三个主要派生量:
\begin{aligned}
P_{\mathrm{cyl}} &= P\left(\rho_{\mathrm{cyl}},u_{\mathrm{cyl}}\right) \\
T_{\mathrm{cyl}} &= T\left(\rho_{\mathrm{cyl}},u_{\mathrm{cyl}}\right) \\
h_{\mathrm{cyl}} &= h\left(\rho_{\mathrm{cyl}},u_{\mathrm{cyl}}\right)
\end{aligned}
对应代码:
P:src/cylinder/gas_cylinder.py:74-77T:src/cylinder/gas_cylinder.py:79-82h:src/cylinder/gas_cylinder.py:84-87
当前模型只保留上述三个热力派生量,不再保留额外的热物性辅助输出。
5. 边界 ghost state 计算
ghost_state() 用于给一维守恒流动模型提供气瓶侧边界状态,代码位置为 src/cylinder/gas_cylinder.py:89-97。
返回向量为:
\mathbf{q}_{\mathrm{ghost}}=
\left[
\rho_{\mathrm{cyl}},\
0,\
\rho_{\mathrm{cyl}}u_{\mathrm{cyl}}
\right]^T
三个分量分别是:
| 分量 | 代码表达 | 物理意义 |
|---|---|---|
q_1 |
self.rho |
质量密度 |
q_2 |
0.0 |
动量密度 |
q_3 |
self.rho * self.specific_internal_energy |
总能量密度 |
由于气瓶是 0D 静止控制体,边界 ghost state 的速度取 0,所以动量密度为 0。总能量密度中也没有宏观动能项:
\rho E = \rho u + \frac{1}{2}\rho v^2 = \rho u \quad \left(v=0\right)
注意:这个 ghost state 使用的是真实流体内能。如果下游管路求解器使用理想气体状态方程,耦合前需要确认状态方程和能量定义是否一致。
6. 边界通量更新计算
apply_flux(mdot, edot, dt, sign) 根据外部边界通量更新气瓶守恒量,代码位置为 src/cylinder/gas_cylinder.py:99-128。
输入量含义:
| 参数 | 单位 | 含义 |
|---|---|---|
mdot |
kg/s | 边界质量流率 |
edot |
W | 边界能量流率 |
dt |
s | 时间步长 |
sign |
- | 通量方向符号 |
方向符号定义为:
s=
\begin{cases}
-1, & \text{气体从气瓶流出} \\
+1, & \text{气体流入气瓶}
\end{cases}
离散更新方程为:
\begin{aligned}
m_{\mathrm{cyl}}^{n+1} &= m_{\mathrm{cyl}}^{n}+s\dot{m}\Delta t \\
U_{\mathrm{cyl}}^{n+1} &= U_{\mathrm{cyl}}^{n}+s\dot{E}\Delta t
\end{aligned}
代码中对应:
self.mass += sign * mdot * dt
self.U += sign * edot * dt
连续形式为:
\begin{aligned}
\frac{dm_{\mathrm{cyl}}}{dt} &= s\dot{m} \\
\frac{dU_{\mathrm{cyl}}}{dt} &= s\dot{E}
\end{aligned}
如果外部模型使用边界比焓计算能量流率,常见形式为:
\dot{E}=\dot{m}h_{\mathrm{boundary}}
但气瓶模型本身不强制 edot = mdot * h,只接收外部传入的能量流率。这使它可以用于不同边界模型,但也要求调用方保证质量通量和能量通量的物理一致性。
6.1 数值保护
通量更新前后包含三类保护:
\Delta t\ge0,\quad s\in\{-1,+1\},\quad m_{\mathrm{cyl}}^{n+1}>0
对应行为:
dt < 0时抛出ValueError。sign不是-1或+1时抛出ValueError。- 更新后
mass <= 0时抛出RuntimeError。 - 更新完成后立即调用
_update_state(),让 CoolProp 立刻检查新的(\rho,u)是否处于有效热力状态。
7. 状态汇总
state_summary() 返回当前气瓶状态字典,代码位置为 src/cylinder/gas_cylinder.py:130-142。
返回字段为:
| 字段 | 含义 |
|---|---|
fluid |
工质名称 |
V |
气瓶固定容积 |
mass |
当前总质量 |
rho |
当前平均密度 |
P |
当前绝对压力 |
T |
当前温度 |
U |
当前总内能 |
u |
当前比内能 |
h |
当前比焓 |
该函数主要用于后处理、日志输出或快速检查模型状态。
8. 耦合使用简述
在低温贮箱和气瓶耦合示例中,气瓶状态通常作为整体 ODE 状态向量的一部分:
\mathbf{y}=\left[m_{\mathrm{liq}},\ U_{\mathrm{liq}},\ T_{\mathrm{ull}},\ m_{\mathrm{cyl}},\ U_{\mathrm{cyl}}\right]
气瓶向贮箱供气时,可写为:
\frac{dm_{\mathrm{cyl}}}{dt}=-\dot{m}_{\mathrm{to\ tank}},\quad
\frac{dU_{\mathrm{cyl}}}{dt}=-\dot{E}_{\mathrm{to\ tank}}
并可用气瓶压力相对贮箱工作压力的差值作为终止条件:
g(t,\mathbf{y})=P_{\mathrm{cyl}}-P_{\mathrm{work}}
示例代码位置:examples/cryo_tank_cylinder_system.py
9. 运行和测试
气瓶模型可直接导入使用:
from cylinder import HighPressureGasCylinder
cylinder = HighPressureGasCylinder()
summary = cylinder.state_summary()
相关测试覆盖默认状态、可配置输入、状态汇总字段、ghost state、出流通量更新和非法输入校验。测试命令:
pytest -q tests/test_gas_cylinder.py