codex/persistent-superconducting-current-decay-bound.py

persistent-superconducting-current-decay-bound.py
"""Original illustrative RL curves, log slopes and a finite-observation bound.

Tested with Python 3.14, matplotlib 3.10.7 and numpy 2.3.5.
Run from _media; writes this script's basename with a .png suffix to CWD.
No plotted quantity is a historical measurement.
"""
from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np


def main():
    plt.rcParams.update({"font.size": 10, "font.family": "DejaVu Sans"})
    inductance = 1e-6
    hours = np.linspace(0, 24, 481)
    resistances = (0, 1e-13, 1e-11)
    colors = ("#23806c", "#185b97", "#bb472a")
    fig, axes = plt.subplots(1, 3, figsize=(11, 4.4), facecolor="white")
    for resistance, color in zip(resistances, colors):
        log_ratio = -resistance * (hours * 3600) / inductance
        ratio = np.exp(log_ratio)
        label = "$R=0$" if resistance == 0 else rf"$R=10^{{{int(np.log10(resistance))}}}\,\Omega$"
        axes[0].plot(hours, ratio, color=color, label=label, lw=2)
        axes[1].plot(hours, log_ratio, color=color, lw=2)
    axes[0].set(xlabel="Elapsed time (hours)", ylabel="$I(t)/I_0$",
                ylim=(.38, 1.025), title="A  Chosen decay models")
    axes[0].legend(loc="lower left", fontsize=9)
    axes[1].set(xlabel="Elapsed time (hours)", ylabel=r"$\ln[I(t)/I_0]$",
                title="B  Logarithmic slope")
    axes[1].text(.05, .07, r"$d\ln I/dt=-R/L$" + "\nConstant $L$, constant $R$, no drive",
                 transform=axes[1].transAxes, fontsize=9)
    epsilon = .001
    duration_hours = np.linspace(1, 24, 300)
    resistance_bound = -inductance * np.log1p(-epsilon) / (duration_hours * 3600)
    axes[2].plot(duration_hours, resistance_bound, color="#654b96", lw=2)
    chosen_bound = -inductance * np.log1p(-epsilon) / (3 * 3600)
    axes[2].plot(3, chosen_bound, "o", color="#654b96")
    axes[2].annotate("3 h: $R\\leq9.26\\times10^{-14}\\,\\Omega$", xy=(3, chosen_bound),
                     xytext=(5, 1.6e-13), fontsize=9,
                     arrowprops={"arrowstyle": "-", "color": "#654b96"})
    axes[2].set(xlabel="Observation window (hours)", ylabel="Resistance upper bound (ohms)",
                yscale="log", ylim=(9e-15, 3.1e-13), title="C  Unresolved loss ≤ 0.1%")
    for ax in axes:
        ax.set_xlim(0, 24)
        ax.set_xticks((0, 6, 12, 18, 24))
        ax.grid(alpha=.22)
        ax.spines[["top", "right"]].set_visible(False)
    fig.suptitle("Illustrative closed loop: $L=1\\,\\mu\\mathrm{H}$; no historical data", fontsize=13)
    fig.text(.5, .025, "A bound requires a calibrated current ratio including field-background, gain and geometry drift.",
             ha="center", fontsize=10)
    fig.subplots_adjust(left=.065, right=.985, bottom=.19, top=.79, wspace=.36)
    fig.savefig(Path(__file__).stem + ".png", dpi=120, facecolor="white")
    plt.close(fig)


if __name__ == "__main__":
    main()