Files

113 lines
3.4 KiB
Python

# tests/cryo_tank/test_tank_model.py
"""Tests for CryoTank model."""
import pytest
import numpy as np
from cryo_tank.tank_model import CryoTank
from cryo_tank.heat_leak import MLIHeatLeak
from cryo_tank.config import (
V_TOTAL, H_TANK, A_CROSS, A_TOTAL, P_WORKING,
T_INIT, ULLAGE_FRACTION,
MDOT_IN_LN2, T_IN_LN2, MDOT_OUT_LN2, T_IN_HE,
H_CONV_SURFACE, T_ENV,
)
def _make_tank(**overrides):
"""Create a CryoTank with default config and MLI heat leak."""
kw = dict(
V_total=V_TOTAL, H_tank=H_TANK,
P_work=P_WORKING,
T_init=T_INIT, ullage_fraction=ULLAGE_FRACTION,
mdot_in_ln2=MDOT_IN_LN2, T_in_ln2=T_IN_LN2,
mdot_out_ln2=MDOT_OUT_LN2,
T_in_he=T_IN_HE,
h_conv=H_CONV_SURFACE, T_env=T_ENV,
heat_leak_model=MLIHeatLeak(A_total=A_TOTAL, q_mli=1.0),
)
kw.update(overrides)
return CryoTank(**kw)
class TestGeometry:
def test_cross_section_area(self):
tank = _make_tank()
assert abs(tank.A_cross - 0.8402) < 0.001
def test_total_surface_area(self):
tank = _make_tank()
assert abs(tank.A_total - 3.305) < 0.01
def test_wetted_area_at_70_percent_fill(self):
tank = _make_tank()
level = 0.7 * H_TANK # 0.35 m
A_wet, A_dry = tank.wetted_areas(level)
# A_wet = bottom cap + side * level
expected_wet = A_CROSS + np.pi * tank.D * level
assert abs(A_wet - expected_wet) < 0.01
assert abs(A_wet + A_dry - A_TOTAL) < 0.01
class TestInitialState:
def test_initial_liquid_mass(self):
tank = _make_tank()
y0 = tank.initial_state()
m_liq = y0[0]
# rho_LN2(78K, 0.17MPa) ~ 803.3 kg/m3, V_liq = 0.2941 m3
assert 235 < m_liq < 237 # ~236.25 kg
def test_initial_fill_fraction(self):
tank = _make_tank()
y0 = tank.initial_state()
info = tank.derive(y0)
assert abs(info['fill_fraction'] - 0.70) < 0.01
def test_initial_temperatures(self):
tank = _make_tank()
y0 = tank.initial_state()
info = tank.derive(y0)
assert abs(info['T_liq'] - T_INIT) < 0.1
assert abs(info['T_ull'] - T_INIT) < 1.0
def test_initial_pressure_is_provided_entirely_by_helium(self):
tank = _make_tank()
y0 = tank.initial_state()
info = tank.derive(y0)
P_He = info['P_He']
assert abs(P_He - P_WORKING) / P_WORKING < 1e-12
class TestVolumeRate:
def test_ullage_volume_rate_includes_liquid_thermal_expansion(self):
tank = _make_tank(
mdot_in_ln2=0.0,
mdot_out_ln2=0.0,
h_conv=0.0,
)
y0 = tank.initial_state()
info = tank.derive(y0)
Q_liq_to_ull = 0.0
Q_leak = tank.heat_leak_model.compute(info['T_liq'], tank.T_env)
A_wet, A_dry = tank.wetted_areas(info['liquid_level'])
Q_leak_liq = Q_leak * A_wet / (A_wet + A_dry)
dU_liq_dt = tank._liquid_energy_rate(
info, Q_liq_to_ull, Q_leak_liq
)
dV_ull_dt = tank._ullage_volume_rate(
info, tank.dm_liq_dt, dU_liq_dt
)
y_next = y0.copy()
dt = 1.0
y_next[1] += dU_liq_dt * dt
finite_difference = (
tank.derive(y_next)['V_ull'] - info['V_ull']
) / dt
assert dV_ull_dt < 0.0
assert abs(dV_ull_dt - finite_difference) / abs(finite_difference) < 1e-5