56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
"""
|
|
End-to-end conservation tests: after a short run, total system mass
|
|
and total system energy must be conserved to machine precision. These
|
|
are the load-bearing tests for the "flux doubling" coupling mechanism.
|
|
"""
|
|
import numpy as np
|
|
import pytest
|
|
from tank import Tank
|
|
from pipe import Pipe
|
|
from solver import run
|
|
|
|
|
|
GAMMA = 1.4
|
|
R_GAS = 287.0
|
|
|
|
|
|
def _build_scenario():
|
|
"""Default blowdown scenario at smaller scale — same physics, short run."""
|
|
tank1 = Tank(V=5.0, P_init=10e6, T_init=300.0, gamma=GAMMA, R_gas=R_GAS)
|
|
tank2 = Tank(V=10.0, P_init=101325.0, T_init=300.0, gamma=GAMMA, R_gas=R_GAS)
|
|
pipe = Pipe(L=1.0, D=5e-3, N=20,
|
|
P_init=101325.0, T_init=300.0, gamma=GAMMA, R_gas=R_GAS)
|
|
return tank1, tank2, pipe
|
|
|
|
|
|
def _total_mass(tank1, tank2, pipe):
|
|
return tank1.mass + tank2.mass + float(np.sum(pipe.W[0, :] * pipe.area * pipe.dx))
|
|
|
|
|
|
def _total_energy(tank1, tank2, pipe):
|
|
return tank1.U + tank2.U + float(np.sum(pipe.W[2, :] * pipe.area * pipe.dx))
|
|
|
|
|
|
def test_total_mass_conserved_over_short_run():
|
|
tank1, tank2, pipe = _build_scenario()
|
|
m_init = _total_mass(tank1, tank2, pipe)
|
|
run(tank1, tank2, pipe, t_end=1e-3, cfl=0.5)
|
|
m_final = _total_mass(tank1, tank2, pipe)
|
|
rel_err = abs(m_final - m_init) / m_init
|
|
assert rel_err < 1e-10, (
|
|
f"Total mass not conserved: m_init={m_init:.6e}, "
|
|
f"m_final={m_final:.6e}, rel_err={rel_err:.2e}"
|
|
)
|
|
|
|
|
|
def test_total_energy_conserved_over_short_run():
|
|
tank1, tank2, pipe = _build_scenario()
|
|
U_init = _total_energy(tank1, tank2, pipe)
|
|
run(tank1, tank2, pipe, t_end=1e-3, cfl=0.5)
|
|
U_final = _total_energy(tank1, tank2, pipe)
|
|
rel_err = abs(U_final - U_init) / U_init
|
|
assert rel_err < 1e-10, (
|
|
f"Total energy not conserved: U_init={U_init:.6e}, "
|
|
f"U_final={U_final:.6e}, rel_err={rel_err:.2e}"
|
|
)
|