"""Original switched-sinusoid RC response and a specified settling threshold.""" from pathlib import Path import matplotlib.pyplot as plt import numpy as np def main(): tau = 1e-3 omega = 1000.0 amplitude = 1.0 ratio = omega * tau t = np.linspace(0, 12 * tau, 2401) steady = amplitude * (np.cos(omega * t) + ratio * np.sin(omega * t)) / (1 + ratio**2) transient = -amplitude * np.exp(-t / tau) / (1 + ratio**2) exact = steady + transient derivative = amplitude * (-omega * np.sin(omega * t) + ratio * omega * np.cos(omega * t) + np.exp(-t / tau) / tau) / (1 + ratio**2) assert exact[0] == 0 assert np.allclose(tau * derivative + exact, amplitude * np.cos(omega * t)) relative = np.exp(-t / tau) / np.sqrt(1 + ratio**2) tolerance = 0.01 settling = tau * np.log(1 / (tolerance * np.sqrt(1 + ratio**2))) assert np.isclose(settling / tau, 4.258596595708118) assert np.allclose(abs(transient) / (amplitude / np.sqrt(1 + ratio**2)), relative) fig, (response, decay) = plt.subplots(1, 2, figsize=(9.6, 4.2), dpi=100, layout="constrained") fig.set_facecolor("white") response.plot(t * 1000, steady, "--", color="#286f99", label="Phasor steady state") response.plot(t * 1000, exact, color="#b66b31", label="Exact switch-on response") response.scatter([0, 0], [0.5, 0], color=["#286f99", "#b66b31"], s=22, zorder=4) response.set(ylabel="Capacitor potential difference (V)", title="The initial condition requires a transient", ylim=(-0.85, 1.15)) response.legend(fontsize=8.5, loc="upper right") decay.semilogy(t * 1000, 100 * relative, color="#286f99", label="Relative transient") decay.axhline(100 * tolerance, color="#444444", linestyle="--", label="1% allowance") decay.axvline(settling * 1000, color="#b66b31", linestyle=":", label=f"Settled after {settling * 1000:.3f} ms") decay.set(ylabel="Transient / steady-state amplitude (%)", ylim=(1e-4, 120), title="An exponential error bound sets the wait") decay.legend(fontsize=8.5, loc="upper right") for ax in [response, decay]: ax.set(xlabel="Time after switch-on (ms)", xlim=(0, 12)) ax.grid(alpha=0.15) fig.savefig(Path(__file__).with_suffix(".png").name, facecolor="white") plt.close(fig) if __name__ == "__main__": main()