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_propertiesFunction
gas_properties(species::String, p::Float64)

This function returns the thermodynamic properties of a saturated vapor.

🔃 Inputs and Outputs

Inputs:

  • species::String: Species name
  • p::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)
source
TASOPT.CryoTank.liquid_propertiesFunction
liquid_properties(species::String, p::Float64)

This function returns the thermodynamic properties of a saturated liquid.

🔃 Inputs and Outputs

Inputs:

  • species::String: Species name
  • p::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)
source

Saturated mixtures

TASOPT.CryoTank.update_pβ!Function

update_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 mixture
  • p::Float64: pressure (Pa)
  • β::Float64: liquid fill ratio

Outputs: No direct outputs. The mixture input is modified.

source

Pressure evolution

TASOPT.CryoTank.dpdtFunction
dpdt(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 tank
  • Q::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 tank
  • mdot_vent::Float64: required venting mass flow rate to keep tank pressure constant (kg/s)
  • xvent::Float64: quality of mixture that is vented
  • V::Float64: tank volume (m^3)
  • α::Float64: fudge factor to account for effect of stratification

Outputs:

  • dp_dt::Float64: pressure derivative in time (Pa/s)
source
TASOPT.CryoTank.dβdtFunction
dβ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 tank
  • dp_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)
source
TASOPT.CryoTank.venting_mass_flowFunction
venting_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 tank
  • Q::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 tank
  • xvent::Float64: quality of the mixture that is vented

Outputs:

  • mdot_vent::Float64: venting mass flow rate (kg/s)
source
TASOPT.CryoTank.mdot_boiloffFunction
mdot_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 tank
  • dβ_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)
source
TASOPT.CryoTank.TankDerivativesFunction
TankDerivatives(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 rate
  • params::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
source

TASOPT interfacing

TASOPT.CryoTank.find_mdot_timeFunction
find_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 parameters
  • parg::Vector{Float64}: vector with aircraft geometric parameters
  • para::Array{Float64}: array with aircraft aerodynamic parameters
  • pare::Array{Float64}: array with aircraft engine parameters

Outputs:

  • t::mdot: fuel mass flow rate out of the tank (kg/s)
source
TASOPT.CryoTank.calc_Q_pointsFunction
calc_Q_points(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 parameters
  • pari::Vector{Int64}: vector with aircraft Boolean and integer parameters
  • parg::Vector{Float64}: vector with aircraft geometric parameters
  • pare::Array{Float64}: array with aircraft engine parameters

Outputs:

  • Qs::Vector{Float64}: vector with heat transfer rate at mission points (W)
source
TASOPT.CryoTank.find_Q_time_interpFunction
find_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 parameters
  • Qs::Vector{Float64}: vector with heat transfer rate at mission points (W)

Outputs:

  • Q::Float64: heat transfer rate (W)
source
TASOPT.CryoTank.analyze_TASOPT_tankFunction
analyze_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 model
  • t_hold_orig::Float64: hold at origin (s)
  • t_hold_dest::Float64: hold at destination (s)

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 time
  • Ms::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)
source
  • 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.