codex/vacuum-pump-down.py

vacuum-pump-down.py
"""Render an original constant-gas-load vacuum model to the current directory.

Run through ``make _media/vacuum-pump-down.png``. Units here are Pa, L,
and seconds; the stipulated gas load is in Pa L/s. These are model curves,
not measurements or a pump specification.
"""
from pathlib import Path

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np


def main():
    volume = 10.0
    gas_load = 1e-5
    initial_pressure = 0.1
    time = np.linspace(0.0, 120.0, 601)
    fig, ax = plt.subplots(figsize=(7.2, 4.6), layout="constrained")
    fig.patch.set_facecolor("white")
    for speed, color in [(0.5, "#b85b19"), (2.0, "#176b91")]:
        pressure_floor = gas_load / speed
        pressure = pressure_floor + (initial_pressure - pressure_floor) * np.exp(
            -speed * time / volume
        )
        ax.semilogy(time, pressure, color=color, linewidth=2,
                    label=f"Effective pumping speed {speed:g} L/s; time constant {volume / speed:g} s")
        ax.axhline(pressure_floor, color=color, linestyle="--", linewidth=1)
        ax.text(118, pressure_floor * 1.2, f"Q/S = {pressure_floor:g} Pa",
                ha="right", va="bottom", color=color, fontsize=9)
    ax.set(xlabel="Time since pumping starts (s)", ylabel="Pressure (Pa)",
           title="Gas load sets a floor even while pumping continues",
           xlim=(0, 120), ylim=(2e-6, 0.2))
    ax.grid(True, which="both", alpha=0.18)
    ax.legend(loc="upper right", fontsize=8, framealpha=1)
    fig.text(0.5, -0.01, "Stipulated model: V = 10 L; Q = 10⁻⁵ Pa L/s; initial pressure = 0.1 Pa",
             ha="center", fontsize=9)
    fig.savefig(Path("vacuum-pump-down.png"), dpi=125, facecolor="white",
                bbox_inches="tight")
    plt.close(fig)


if __name__ == "__main__":
    main()