codexpast-exam-of-the-cosmology-course-of-the-university-of-oxford2025-open-universe-growth.py
past-exam-of-the-cosmology-course-of-the-university-of-oxford/2025-open-universe-growth.py
"""Plot the regular open-dust growth mode; write only to the working directory.
Tested with Python 3.14, NumPy 2.3.5 and Matplotlib 3.10.7.
Run from the corresponding _media directory to regenerate the PNG.
"""
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
def growth(x):
"""Use a series near zero to avoid cancellation in the elementary formula."""
x = np.asarray(x, dtype=float)
result = np.empty_like(x)
small = x < 0.005
y = x[small]
result[small] = 2*y/5 - 8*y**2/35 + 16*y**3/105 - 128*y**4/1155
y = x[~small]
result[~small] = 1 + 3/y - 3*np.sqrt((1+y)/y**3)*np.arcsinh(np.sqrt(y))
return result
def main():
plt.rcParams.update({"font.size": 12, "axes.titlesize": 15})
x = np.geomspace(1e-3, 1e4, 900)
fig, ax = plt.subplots(figsize=(9, 5.2), dpi=110, layout="constrained", facecolor="white")
ax.set_facecolor("white")
ax.loglog(x, growth(x), color="#165a93", lw=2.8, label=r"Regular mode $\delta_2(x)$")
early = x[x < 1.5]
ax.loglog(early, 2*early/5, "--", color="#bf5a19", lw=1.8, label=r"Early limit: $2x/5$")
ax.axhline(1, color="#3b7656", ls="--", lw=1.8, label="Late limit: 1")
ax.axvline(1, color="#777777", ls=":", lw=1.5)
ax.text(1.2, 0.001, "Matter and curvature\ncontribute equally", fontsize=11, color="#555555")
ax.set(xlim=(1e-3, 1e4), ylim=(2e-4, 1.7), xlabel=r"Matter-to-curvature transition variable $x=(1-\Omega)a/\Omega$", ylabel=r"Density-growth mode $\delta_2$", title="Linear density growth freezes in an open dust universe")
ax.grid(which="major", alpha=0.22)
ax.legend(loc="upper left", framealpha=1)
fig.savefig(Path.cwd() / "2025-open-universe-growth.png", facecolor="white", transparent=False)
plt.close(fig)
if __name__ == "__main__":
main()