Homogeneous model
In a tank containing a boiling liquid, such as a cryogenic liquid that has reached its saturation point, two fluid states exist: a liquid phase and a gas phase (or vapor). In a real tank, there would be some level of stratification leading to temperature differences between the two phases, which exist at the same pressure. This section describes the models used to simulate the evolution in time of the conditions inside a cryogenic tank. It is based on the homogeneous tank model[1][2][3], which treats the fluid inside the tank as a well-mixed saturated mixture at homogeneous temperature and pressure.
Theory
📖 Theory - Homogeneous model
Ordinary-differential equation system
Let us consider a tank that contains a mixture of saturated liquid and gas phases at a saturation pressure $p$. The tank has a heat rate $\dot{Q}$ into it and a work rate $\dot{W}$ is performed in the tank. The tank also has a mass flow rate $\dot{m}$ out of the tank of a fluid with quality $x_{out}$. In general, the tank may also be vented with a venting mass flow rate $\dot{m}_{vent}$ of fluid with a quality $x_{vent}$. From conservation of energy, it can be shown that the derivative in time of the saturation pressure in this homogeneous case is[2]
\[ \left( \frac{dp}{dt}\right)_h = \frac{\phi}{V}\left[\dot{Q} + \dot{W} - \dot{m} h_{vap} (x_{out} + \rho ^*) - \dot{m}_{vent} h_{vap} (x_{vent} + \rho ^*)\right],\]
where $\phi$ is the energy derivative of the fluid mixture (to be defined later), $V$ is the tank volume, $h_{vap}$ is the enthalpy of vaporization of the liquid, and $\rho ^*=\frac{\rho_g}{\rho_l-\rho_g}$ is the density ratio ($l$ refers to the properties of the liquid phase and $g$ to those of the gaseous phase). The enthalpy of vaporization is simply the enthalpy difference between the gaseous and liquid phases.
Experiments suggest that the pressure derivative in a real tank can be significantly greater than that of the homogeneous model due to stratification. Authors have accounted for this with a scaling factor $\alpha$, such that[2][3]
\[ \frac{dp}{dt} = \alpha \left( \frac{dp}{dt}\right)_h. \]
If the liquid volume fraction (fill fraction) if the tank is $\beta$, the density of the mixture can be expressed as
\[ \rho = \beta \rho_l + (1-\beta) \rho_g.\]
Differentiating this in time,
\[ \frac{d\rho}{dt} = \frac{d \beta}{dt} (\rho_l - \rho_g) + \beta \frac{d\rho_l}{dp}\frac{dp}{dt} + (1-\beta) \frac{d\rho_g}{dp} \frac{dp}{dt},\]
where the liquid- and gas-phase densities are functions of pressure only since the fluid is in saturated conditions. The derivative in time of density in the tank is equal to
\[ \frac{d\rho}{dt} = -\frac{\dot{m} + \dot{m}_{vent}}{V}.\]
Solving for the rate of change of the fill volume in the tank,
\[ \frac{d\beta}{dt} = \frac{1}{\rho_l - \rho_g}\left[\frac{d\rho}{dt} - \frac{dp}{dt} \left(\beta \frac{d\rho_l}{dp}+(1-\beta) \frac{d\rho_g}{dp}\right)\right].\]
The evolution in time of properties inside the tank can be modeled by solving the system of ordinary differential equations (ODEs) given by
\[ \frac{d}{dt} \mathbf{x} = \mathbf{f}(t, \mathbf{x}, \mathbf{u}, \mathbf{p}),\]
where $\mathbf{x} = [p, \beta]^T$, $\mathbf{u} = [\dot{Q}(t), \dot{W}(t), \dot{m}(t)]^T$ and $\mathbf{p} = [V, \alpha, p_{vent}]^T$, where $p_{vent}$ is the pressure at which the tank is vented. These ODEs can be integrated in time from knowledge of the initial conditions, namely the initial pressure and initial tank fill fraction.
Energy derivative
The energy derivative $\phi$ is given by[1]
\[ \phi = \frac{1}{\rho \left(\frac{\partial u}{\partial p}\right)_\rho},\]
where $u$ represents the internal energy of the mixture. The partial derivative $\left(\frac{\partial u}{\partial p}\right)_\rho$ is taken at constant mixture density. The internal energy of the mixture is given by
\[ u = x u_g + (1-x) u_l,\]
where $x$ represents the quality of the mixture (the mass fraction of the gaseous phase). Differentiating this in pressure at constant mixture density,
\[ \left(\frac{\partial u}{\partial p}\right)_\rho = x \frac{du_g}{dp} + (1-x)\frac{du_l}{dp} + (u_g - u_l) \left(\frac{\partial x}{\partial p}\right)_\rho.\]
The density of the mixture can be related to the quality by[1]
\[ \frac{1}{\rho} = \frac{x}{\rho_g} + \frac{1-x}{\rho_l}.\]
Differentiating in pressure at constant mixture density yields
\[ \left(\frac{\partial x}{\partial p}\right)_\rho = \left(\frac{1}{1/\rho_g - 1/\rho_l}\right)\left(\frac{x}{\rho_g^2}\frac{d\rho_g}{dp} + \frac{1-x}{\rho_l^2}\frac{d\rho_l}{dp}\right),\]
which completes the expression for the energy derivative.
Venting
Venting may be needed when the tank pressure has reached some maximum pressure. The purpose of mass venting from the tank is to prevent the tank pressure from increasing any further. To find the required venting mass flow rate, the equation for $\frac{dp}{dt}$ can be set to zero whenever the venting pressure $p_{vent}$ is reached or exceeded, yielding,
\[ \dot{m}_{vent} = \begin{cases} 0, & p<p_{vent}\\ \frac{\dot{Q} + \dot{W}}{h_{vap} (x_{vent} + \rho^*)} - \frac{x_{out} + \rho^*}{x_{vent} + \rho ^*}\dot{m}, &p\geq p_{vent} \end{cases}.\]
Functions
Thermodynamic properties
TASOPT.CryoTank.gas_properties
— Functiongas_properties(species::String, p::Float64)
This function returns the thermodynamic properties of a saturated vapor.
🔃 Inputs and Outputs
Inputs:
species::String
: Species namep::Float64
: pressure (Pa)
Outputs:
Tsat::Float64
: temperature (K)ρ::Float64
: density (kg/m^3)ρ_p::Float64
: derivative of density with pressure (kg/m^3/Pa)h::Float64
: specific enthalpy (J/kg)u::Float64
: specific internal energy (J/kg)u_p::Float64
: derivative of internal energy with pressure (J/kg/Pa)
TASOPT.CryoTank.liquid_properties
— Functionliquid_properties(species::String, p::Float64)
This function returns the thermodynamic properties of a saturated liquid.
🔃 Inputs and Outputs
Inputs:
species::String
: Species namep::Float64
: pressure (Pa)
Outputs:
Tsat::Float64
: temperature (K)ρ::Float64
: density (kg/m^3)ρ_p::Float64
: derivative of density with pressure (kg/m^3/Pa)h::Float64
: specific enthalpy (J/kg)u::Float64
: specific internal energy (J/kg)u_p::Float64
: derivative of internal energy with pressure (J/kg/Pa)
Saturated mixtures
TASOPT.CryoTank.SaturatedGas
— TypeStructure with thermodynamic parameters for the vapor portion of a saturated mixture.
TASOPT.CryoTank.SaturatedLiquid
— TypeStructure with thermodynamic parameters for the liquid portion of a saturated mixture.
TASOPT.CryoTank.SaturatedMixture
— TypeStructure with thermodynamic properties of a saturated mixture.
TASOPT.CryoTank.update_pβ!
— Functionupdate_pβ!(mixture, p, β)
This function updates a saturated mixture when there is a change in pressure or liquid fill volume ratio.
🔃 Inputs and Outputs
Inputs:
mixture::SaturatedMixture
: saturated mixturep::Float64
: pressure (Pa)β::Float64
: liquid fill ratio
Outputs: No direct outputs. The mixture
input is modified.
Pressure evolution
TASOPT.CryoTank.dpdt
— Functiondpdt(mixture, Q, W, mdot, xout, V)
This function returns the time derivatives for the pressure in a cryogenic tank.
🔃 Inputs and Outputs
Inputs:
mixture::SaturatedMixture
: liquid/vapor mixture in tankQ::Float64
: heat rate (W)W::Float64
: work rate (W)mdot::Float64
: imposed mass flow rate out of the tank, e.g., to burn in combustor (kg/s)xout::Float64
: quality of mass flow rate out of tankmdot_vent::Float64
: required venting mass flow rate to keep tank pressure constant (kg/s)xvent::Float64
: quality of mixture that is ventedV::Float64
: tank volume (m^3)α::Float64
: fudge factor to account for effect of stratification
Outputs:
dp_dt::Float64
: pressure derivative in time (Pa/s)
TASOPT.CryoTank.dβdt
— Functiondβdt(mixture, dp_dt, mdot, V)
This function returns the time derivatives for the liquid fill volume fraction in a cryogenic tank.
🔃 Inputs and Outputs
Inputs:
mixture::SaturatedMixture
: liquid/vapor mixture in tankdp_dt::Float64
: pressure derivative (Pa/s)mdot_tot::Float64
: total mass flow rate out of the tank, including venting (kg/s)V::Float64
: tank volume (m^3)
Outputs:
dβ_dt::Float64
: fill fraction derivative in time (1/s)
TASOPT.CryoTank.venting_mass_flow
— Functionventing_mass_flow(mixture, Q, W, mdot, xout, xvent)
This function returns the mass flow rate that needs to be vented to keep the tank pressure constant.
🔃 Inputs and Outputs
Inputs:
mixture::SaturatedMixture
: liquid/vapor mixture in tankQ::Float64
: heat rate (W)W::Float64
: work rate (W)mdot::Float64
: mass flow rate out of the tank (kg/s)xout::Float64
: quality of mass flow rate out of tankxvent::Float64
: quality of the mixture that is vented
Outputs:
mdot_vent::Float64
: venting mass flow rate (kg/s)
TASOPT.CryoTank.mdot_boiloff
— Functionmdot_boiloff(β, dβ_dt, dp_dt, ρl, ρl_p, mdot, V)
This function returns the rate of mass boiloff in the tank.
🔃 Inputs and Outputs
Inputs:
mixture::SaturatedMixture
: liquid/vapor mixture in tankdβ_dt::Float64
: fill fraction derivative in time (1/s)dp_dt::Float64
: pressure derivative (Pa/s)mdot_liq::Float64
: liquid-phase mass flow rate out of the tank (kg/s)V::Float64
: tank volume (m^3)
Outputs:
mdot_boiloff::Float64
: rate of liquid mass boiloff (kg/s)
TASOPT.CryoTank.TankDerivatives
— FunctionTankDerivatives(t, y, u, params)
This function returns the time derivatives for pressure and liquid volume fill fraction in a cryogenic tank.
🔃 Inputs and Outputs
Inputs:
t::Float64
: time (s)y::Vector{Float64}
: vector with the states;y[1]
is pressure,y[2]
is fill fraction, y[3] is tank mass,
y[4] is total liquid mass extracted, y[5] is the total mass that is vented and y[6] is the total mass that is boiled off.
u::Struct
: structure with inputs; functions for heat rate, work rate and mass flow rateparams::Struct
: structure with parameters; including initial tank mixture, tank max pressure and tank volume
Outputs:
dydt::Vector{Float64}
: vector with the state derivatives in time
TASOPT interfacing
TASOPT.CryoTank.find_mdot_time
— Functionfind_mdot_time(t, pari, parg, para, pare)
This function outputs the fuel mass flow rate to the engines as a function of time for a TASOPT aircraft model.
🔃 Inputs and Outputs
Inputs:
t::Float64
: time in mission (s)parg::Vector{Float64}
: vector with aircraft integer parametersparg::Vector{Float64}
: vector with aircraft geometric parameterspara::Array{Float64}
: array with aircraft aerodynamic parameterspare::Array{Float64}
: array with aircraft engine parameters
Outputs:
t::mdot
: fuel mass flow rate out of the tank (kg/s)
TASOPT.CryoTank.calc_Q_points
— Functioncalc_Q_points(fuse, fuse_tank, pari, parg, para)
This function calculates the heat transfer rate into the tank at the design mission points.
🔃 Inputs and Outputs
Inputs:
fuse_tank::FuselageTank
: struct with aircraft cryogenic tank parameterspari::Vector{Int64}
: vector with aircraft Boolean and integer parametersparg::Vector{Float64}
: vector with aircraft geometric parameterspare::Array{Float64}
: array with aircraft engine parameters
Outputs:
Qs::Vector{Float64}
: vector with heat transfer rate at mission points (W)
TASOPT.CryoTank.find_Q_time_interp
— Functionfind_Q_time_interp(t, para, Qs)
This function estimates the heat transfer rate into the tank in a TASOPT model for a given time. It uses precomputed rates at each mission point for speed.
🔃 Inputs and Outputs
Inputs:
t::Float64
: time in mission (s)para::Array{Float64}
: array with aircraft aerodynamic parametersQs::Vector{Float64}
: vector with heat transfer rate at mission points (W)
Outputs:
Q::Float64
: heat transfer rate (W)
TASOPT.CryoTank.analyze_TASOPT_tank
— Functionanalyze_TASOPT_tank(ac_orig, t_hold_orig::Float64 = 0.0, t_hold_dest::Float64 = 0.0, N::Int64 = 50)
This function analyses the evolution in time of a cryogenic tank inside a TASOPT aircraft model.
🔃 Inputs and Outputs
Inputs:
ac_orig::aicraft
: TASOPT aircraft modelt_hold_orig::Float64
: hold at origin (s)t_hold_dest::Float64
: hold at destination (s)im::Int64
: mission index
Outputs:
ts::Vector{Float64}
: vector with times (s)ps::Vector{Float64}
: vector with pressure evolution in time (Pa)βs::Vector{Float64}
: vector with tank fill fraction evolution in timeMs::Vector{Float64}
: vector with tank fuel mass evolution in time (kg)Mburns::Vector{Float64}
: vector with cumulative mass burnt in engine (kg)Mboils::Vector{Float64}
: vector with cumulative mass that has boiled off (kg)mdot_boils::Vector{Float64}
: vector with evolution of boiloff mass flow rate in time (kg/s)Mvents::Vector{Float64}
: vector with cumulative mass that has been vented (kg)mdots::Vector{Float64}
: vector with fuel mass flow rate to engines (kg/s)Qs::Vector{Float64}
: vector with heat rate to tank (W)
- 1Lin, Chin S., Neil T. Van Dresar, and Mohammad M. Hasan. "Pressure control analysis of cryogenic storage systems." Journal of propulsion and power 20.3 (2004): 480-485.
- 2Verstraete, Dries, et al. "Hydrogen fuel tanks for subsonic transport aircraft." International journal of hydrogen energy 35.20 (2010): 11085-11098.
- 3Winnefeld, Christopher, et al. "Modelling and designing cryogenic hydrogen tanks for future aircraft applications." Energies 11.1 (2018): 105.