codexliquefaction-enthalpy-fraction-model.py
liquefaction-enthalpy-fraction-model.py
"""Plot an original normalized cold-section enthalpy budget, not helium data.
Tested with Python 3.14, matplotlib 3.10.7 and numpy 2.3.5. Run from _media;
output is liquefaction-enthalpy-fraction-model.png in the current directory.
"""
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def liquid_fraction(eta, heat):
return 1 - np.asarray(eta) - heat
def main():
plt.rcParams.update({"font.size": 11, "font.family": "DejaVu Sans"})
fig, ax = plt.subplots(figsize=(8.8, 5.6), dpi=110, facecolor="white")
fig.subplots_adjust(left=.11, right=.97, bottom=.20, top=.83)
eta = np.linspace(0, 1.10, 551)
for heat, color in [(0, "#185b9b"), (.05, "#087f8c"), (.20, "#b85a20")]:
y = liquid_fraction(eta, heat)
valid = (y >= 0) & (y <= 1)
ax.plot(eta[valid], y[valid], color=color, lw=2.4,
label=rf"Heat input $q/L={heat:g}$")
ax.plot(eta[~valid], y[~valid], color=color, lw=1.4, ls="--")
ax.axhspan(-.32, 0, facecolor="#f2f2f2", hatch="///", edgecolor="#cccccc", lw=0)
ax.axhline(0, color="#555555", lw=1)
ax.scatter([.70], [.25], s=62, color="#087f8c", zorder=5)
ax.annotate("Chosen example\nη = 0.70, q/L = 0.05\ny = 0.25", (.70, .25),
xytext=(.25, .11), fontsize=11,
arrowprops={"arrowstyle": "->", "color": "#087f8c"},
bbox={"boxstyle": "round,pad=.4", "fc": "white", "ec": "#087f8c"})
ax.text(.55, -.20, "Negative algebraic y: no saturated two-phase outlet solution",
fontsize=10, ha="center", va="center", bbox={"fc": "white", "ec": "none"})
ax.set(xlim=(0, 1.1), ylim=(-.32, 1.04),
xlabel=r"Inlet enthalpy above saturated liquid: $\eta=(h_{\rm in}-h_l)/L$",
ylabel=r"Liquid mass fraction $y$")
ax.legend(loc="upper right", framealpha=1, fontsize=10)
ax.grid(alpha=.18)
ax.set_axisbelow(True)
fig.suptitle("How enthalpy and incoming heat limit liquid production", fontsize=15, y=.97)
fig.text(.5, .885, r"$h_{\rm in}+q=yh_l+(1-y)h_g$ • $L=h_g-h_l>0$",
ha="center", fontsize=13)
fig.text(.5, .055, "Dimensionless chosen model • no helium property fit or historical yield\n"
"Steady cold section; equilibrium outlet phases at one pressure; negligible work and motion",
ha="center", fontsize=10, color="#45515e")
# Independently check conservation with a dimensional enthalpy reference.
h_liquid, h_gas, h_in, q = 17., 217., 157., 10.
y = float(liquid_fraction((h_in-h_liquid)/(h_gas-h_liquid), q/(h_gas-h_liquid)))
assert abs(y - .25) < 1e-14
assert abs((h_in+q) - (y*h_liquid + (1-y)*h_gas)) < 1e-12
assert abs(float(liquid_fraction(.70, .30))) < 1e-14
assert float(liquid_fraction(.70, .31)) < 0
fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"), facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()