Files
2026-06-03 15:41:04 +08:00

80 lines
2.7 KiB
Python

# tests/cryo_tank/test_integration.py
"""Integration tests for the cryogenic tank simulation."""
import numpy as np
from cryo_tank.tank_model import CryoTank
from cryo_tank.heat_leak import MLIHeatLeak
from cryo_tank.solver import run
from cryo_tank.config import (
V_TOTAL, H_TANK, P_WORKING, T_INIT, ULLAGE_FRACTION,
MDOT_IN_LN2, T_IN_LN2, MDOT_OUT_LN2, T_IN_HE,
H_CONV_SURFACE, T_ENV, A_TOTAL,
)
def _make_tank(**overrides):
"""Create a tank with default config, allowing overrides."""
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 TestMassConservation:
def test_liquid_mass_change_matches_net_flow(self):
"""Over a short run, dm_liq should equal (mdot_in - mdot_out) * dt."""
tank = _make_tank()
history = run(tank, t_end=10.0, max_step=1.0)
m_liq_0 = history['m_liq'][0]
m_liq_f = history['m_liq'][-1]
t_f = history['t'][-1]
expected_dm = (MDOT_IN_LN2 - MDOT_OUT_LN2) * t_f
actual_dm = m_liq_f - m_liq_0
rel_err = abs(actual_dm - expected_dm) / abs(expected_dm)
assert rel_err < 1e-6, f"Mass conservation error: rel_err={rel_err:.2e}"
class TestSteadyState:
def test_zero_flow_zero_leak_is_static(self):
"""With no flow and no heat leak, state should not change."""
tank = _make_tank(
mdot_in_ln2=0.0,
mdot_out_ln2=0.0,
h_conv=0.0,
heat_leak_model=MLIHeatLeak(A_total=A_TOTAL, q_mli=0.0),
)
history = run(tank, t_end=100.0, max_step=10.0)
T_liq = history['T_liq']
T_ull = history['T_ull']
assert abs(T_liq[-1] - T_liq[0]) < 0.01, f"T_liq drifted: {T_liq[0]:.3f} -> {T_liq[-1]:.3f}"
assert abs(T_ull[-1] - T_ull[0]) < 0.1, f"T_ull drifted: {T_ull[0]:.3f} -> {T_ull[-1]:.3f}"
class TestPhysicalBehavior:
def test_liquid_level_decreases(self):
"""With net outflow, liquid level should decrease."""
tank = _make_tank()
history = run(tank, t_end=60.0, max_step=5.0)
assert history['fill_fraction'][-1] < history['fill_fraction'][0]
def test_he_flow_rate_positive(self):
"""He should always flow in (pressurization), not out."""
tank = _make_tank()
history = run(tank, t_end=60.0, max_step=5.0)
assert np.all(history['mdot_He'] >= -1e-10) # allow tiny numerical noise