Background cosmology and species
The homogeneous universe in Cosmic.jl is a Cosmology: a container of species, each knowing its own energy density $\rho(a)/\rho_{c,0}$ and equation of state $w(a)$. The Friedmann equation is then just the sum
\[\frac{H^2(a)}{H_0^2} = \sum_i \frac{\rho_i(a)}{\rho_{c,0}},\]
and every background quantity — distances, ages, horizons — is an integral over it. Nothing assumes a particular species content, so exotic components (warm or decaying dark matter, quintessence) enter on exactly the same footing as photons and baryons.
Building a cosmology
cosmology() assembles the species from familiar parameters. Two choices are worth spelling out. First, the helium fraction defaults to Yp = :bbn: given $\omega_b$ and $N_{\rm eff}$, nucleosynthesis fixes $Y_p$, so treating it as a free parameter would let a model quietly carry a helium abundance inconsistent with its own baryon density; the network is solved (and cached) instead. Second, dark energy closes the budget: $\Omega_{\rm DE}$ is never an input but whatever flatness (or the requested $\Omega_k$) demands.
Massive neutrinos are never approximated by a power law in $a$. Their density comes from the exact phase-space integral $\rho \propto \int dq\, q^2 \sqrt{q^2 + (ma/T_{\nu,0})^2}\, f_0(q)$, which crosses from radiation-like to matter-like behaviour with no interpolation.
Dark energy
Four options, in increasing generality:
- a cosmological constant (the default,
w0 = -1, wa = 0); - the CPL fluid
w(a) = w0 + wa (1 - a); - an arbitrary
w_func(a), whose density integrates the continuity equation numerically; - a quintessence field: pass a potential
V_scf(in units of the critical density, with the field in reduced Planck masses) and its derivativedV_scf. The Klein–Gordon equation is solved through the full expansion history, with the potential amplitude shot by bisection so the field's density today closes the budget exactly. The field starts frozen — the early-time attractor under Hubble friction — and its $w(a)$ is whatever the potential produces, not a parameterization.
For anything other than the cosmological constant, the corresponding perturbations are evolved automatically (see Linear perturbations); a true $\Lambda$ carries none, exactly.
Dark matter beyond CDM
Warm dark matter (cosmology(m_wdm = ..., Ω_wdm = ...)) is a thermal fermion relic riding the same momentum-resolved machinery as massive neutrinos. Its temperature ratio to the neutrinos follows from the abundance through the exact phase-space integral rather than the usual $93.14\,\mathrm{eV}$ shortcut (which assumes instantaneous-decoupling neutrino temperature and is about 1% off). The free-streaming suppression of structure it produces is computed, not fitted; the resulting cutoff reproduces the Viel transfer function at the few-percent level as an output.
Decaying dark matter (Γ_dcdm in km/s/Mpc, Ω_dcdm_ini the abundance it would have today without decay) converts to a dark radiation component through $\dot\rho_{\rm dcdm} = -3\mathcal{H}\rho_{\rm dcdm} - a\Gamma\rho_{\rm dcdm}$. No closed form exists — the decay is in proper time, so the history depends on the expansion it modifies — and the coupled system is solved at construction, self-consistently with the dark-energy closure. The realised $\Omega_{\rm dcdm}$ today matches the analytic $\Omega_{\rm ini} e^{-\Gamma t_0}$ to five digits, and the full perturbation sector (including the sourced dark-radiation hierarchy) reproduces the decay response of CLASS to better than half a percent in the CMB.
Annihilating dark matter affects the thermal history rather than the background; see Thermal history.
Distances and times
The usual kinematic toolbox — comoving, transverse comoving, angular-diameter and luminosity distances, lookback time, age, conformal time — all as direct integrals over $E(a)$ with curvature handled exactly in open, flat, and closed geometries.
Reference
Cosmic.Cosmology — Type
CosmologyContainer for a background model. Build one with cosmology rather than calling this constructor directly.
Fields beyond the species list:
h: H0 = 100h km/s/MpcTcmb: CMB temperature today, KYp: primordial helium mass fraction (needed by recombination)A_s,n_s,k_pivot: primordial curvature power spectrum, PR(k) = As (k/kpivot)^(ns - 1)
Cosmic.E_z — Method
H(a)/H0 as a function of redshift instead of scale factor.
Cosmic.H_Mpc — Method
Hubble rate in 1/Mpc (the internal unit), as a function of scale factor.
Cosmic.age — Function
age(c, z; unit = :Gyr)Age of the universe at redshift z: t = ∫₀^a da/(a H(a)).
Cosmic.angular_diameter_distance — Method
angular_diameter_distance(c, z₁, z₂)Angular-diameter distance between two redshifts, the quantity gravitational lensing needs. Note this is not DA(z₂) - DA(z₁); the curvature-correct form (Hogg 1999 eq. 19) is used.
Cosmic.angular_diameter_distance — Method
angular_diameter_distance(c, z)DA = DM/(1+z), in Mpc. Physical size = D_A × angle subtended.
Cosmic.comoving_distance — Method
comoving_distance(c, z₁, z₂ = nothing)Line-of-sight comoving distance in Mpc. With one redshift, the distance from us to z₁; with two, the distance between them.
Cosmic.comoving_volume — Method
comoving_volume(c, z)All-sky comoving volume out to z, in Mpc³, with the curvature correction (Hogg 1999 eq. 29).
Cosmic.conformal_time — Method
conformal_time(c, a)Conformal time η = ∫₀^a da'/(a'² H(a')), in Mpc. This is the time variable the Boltzmann hierarchy is integrated in, and it doubles as the comoving particle horizon.
Cosmic.conformal_time_today — Method
Comoving distance to the horizon today, η₀, in Mpc.
Cosmic.cosmology — Method
cosmology(; h, Ω_b, Ω_c, Ω_k, Tcmb, N_eff, m_ν, w0, wa, ...)Build a Cosmology. Defaults are Planck 2018 TT,TE,EE+lowE+lensing+BAO.
Dark energy closes the budget: Ωde = 1 - Ωk - Σ(everything else), evaluated today so that massive neutrinos (which are matter now but were radiation once) are counted correctly.
Neutrinos: m_ν is a vector of masses in eV. Species with mass are given the full phase-space treatment; the remainder of N_eff is carried by massless species. The default m_ν = [0.06, 0.0, 0.0] is the minimal normal hierarchy. Pass m_ν = Float64[] for the (unphysical, but common in older codes) case of three massless neutrinos. Vectors shorter than three are zero-padded under the standard active-neutrino convention. Set N_ν_slots explicitly for a different number of slots. ξ_ν sets mass-slot degeneracies; ξ_νe separately sets the electron-flavour degeneracy entering BBN weak rates. When every slot has the same ξ, ξ_νe is inferred from it.
Dark energy: w0/wa select CPL. For anything more exotic, pass w_func, an arbitrary function of a.
Examples
c = cosmology() # Planck 2018 ΛCDM
c = cosmology(Ω_k = 0.01) # open
c = cosmology(w0 = -0.9, wa = -0.3) # CPL dark energy
c = cosmology(m_ν = [0.1, 0.1, 0.1]) # degenerate 0.3 eV neutrinos
c = cosmology(w_func = a -> -1 + 0.1*(1-a)^2) # arbitrary w(a)Cosmic.distance_modulus — Method
distance_modulus(c, z)μ = 5 log₁₀(D_L / 10 pc), the quantity supernova cosmology is done in.
Cosmic.get_all_species — Method
All species of a given type (there can be several massive neutrinos).
Cosmic.get_species — Method
get_species(c, Type)Return the first species of the given type, or nothing. Used by the thermodynamics and perturbation layers, which need e.g. the baryons specifically rather than just the total density.
Cosmic.hubble_distance — Method
Hubble distance c/H0 in Mpc.
Cosmic.hubble_time — Method
Hubble time 1/H0 in Gyr.
Cosmic.lookback_time — Method
lookback_time(c, z)Time elapsed between redshift z and today, in Gyr.
Cosmic.luminosity_distance — Method
luminosity_distance(c, z)DL = (1+z) DM, in Mpc. Flux = L / (4π D_L²).
Cosmic.scale_factor_of_time — Method
scale_factor_of_time(c, t_Gyr)Invert t(a) to get a(t). Replaces the old ODE-based scale_fact, which integrated da/dt from a = 1e-8 and inherited whatever error that seeding introduced; root-solving the age integral is both faster and exact.
Cosmic.transverse_comoving_distance — Method
transverse_comoving_distance(c, z)Comoving distance transverse to the line of sight, DM. This is where spatial curvature finally shows up: for Ωk ≠ 0 a comoving separation subtends a different angle than it would in flat space, so
D_M = D_H/√Ω_k · sinh(√Ω_k · D_C/D_H) (open, Ω_k > 0)
D_M = D_C (flat, Ω_k = 0)
D_M = D_H/√|Ω_k| · sin (√|Ω_k| · D_C/D_H) (closed, Ω_k < 0)Angular-diameter and luminosity distances are built on DM, not DC, which is the piece the old code was missing.
Cosmic.z_equality — Method
z_equality(c)Redshift of matter-radiation equality, from root-solving ρm(a) = ρr(a).
Cosmic.Ω_de — Method
Dark-energy density today, whatever the flavour.
Cosmic.Ω_r — Method
Radiation density today (the relativistic share 3P of every species).
Cosmic.Ω_ν — Method
Total neutrino density today, massless plus massive.
Cosmic.ρ_matter — Method
ρ_matter(c, a), ρ_radiation(c, a)Non-relativistic and relativistic energy densities, in units of ρ_c0.
For a species with density ρ and pressure P, CLASS separates the relativistic share as 3P and the non-relativistic share as ρ−3P. This is exact in both limits and remains continuous through the massive-neutrino transition. Decaying CDM and its daughter radiation are assigned to their physical sectors.
Cosmic.Baryons — Type
Baryons(Ω_b)Baryonic matter. Dynamically identical to CDM in the background (ρ ∝ a⁻³) but tracked separately: it is tightly coupled to the photons before recombination, and the thermodynamics and perturbation layers need Ω_b on its own.
Cosmic.ColdDarkMatter — Type
ColdDarkMatter(Ω_c)Collisionless, pressureless matter. ρ ∝ a⁻³.
Cosmic.CosmologicalConstant — Type
CosmologicalConstant(Ω_Λ)w = -1 exactly, ρ constant.
Cosmic.Curvature — Type
Curvature(Ω_k)Not a fluid, but it enters E(a)² the same way, with ρeff ∝ a⁻². Sign convention: Ωk > 0 is an open (negatively curved) universe.
Cosmic.DecayingCDM — Type
DecayingCDM(Γ, lnρ) / DecayRadiation(lnρ)Cold dark matter decaying into a relativistic dark radiation with rate Γ (in 1/Mpc, per proper time). Unlike every other species these have no closed-form density: ρ_dcdm ∝ a⁻³ e^{−Γt} needs t(a), which depends on the full expansion history — including the decay products themselves. cosmology() therefore solves the coupled system
d ln ρ_dcdm/dx = −3 − aΓ/ℋ
d ln ρ_dr/dx = −4 + (aΓ/ℋ) ρ_dcdm/ρ_dr, x = ln a, ℋ = aH,self-consistently (fixed-point in the dark-energy closure) and stores the two histories as interpolants carried by this species pair.
Cosmic.FermiDirac — Type
FermiDirac(ξ = 0)Pair-averaged neutrino plus antineutrino Fermi–Dirac distribution
f₀(q) = 1/2 [1/(e^{q−ξ}+1) + 1/(e^{q+ξ}+1)]with degeneracy parameter ξ = μ/T. The antineutrino chemical potential is −μ, so this is the distribution whose energy integral obeys the standard exact even-in-ξ density enhancement. ξ = 0 is the standard case.
Cosmic.GeneralDarkEnergy — Type
GeneralDarkEnergy(Ω_de, w_func)Dark energy with an arbitrary equation of state w_func(a). The density comes from integrating the continuity equation numerically,
ρ(a)/ρ₀ = exp( 3 ∫_a^1 [1 + w(a')] da'/a' )which is slower than the closed forms above but imposes no restriction on the shape of w(a) – early dark energy, quintessence tracker fields, oscillating models all just work.
Cosmic.MassiveNeutrinos — Type
MassiveNeutrinos(Ω_rel, y1)One massive neutrino species. Ω_rel is the density parameter it would have if it stayed massless, and y1 = m c²/(k T_ν,0) is its mass in units of the neutrino temperature today.
Density and pressure follow from the phase-space integral:
ρ(a)/ρ_c0 = Ω_rel · F(y1·a) / F(0) / a⁴The species behaves as radiation while y1·a ≪ 1 and as matter once y1·a ≫ 1, with the transition handled exactly rather than by interpolating between two power laws.
Cosmic.MasslessNeutrinos — Type
MasslessNeutrinos(Ω_ν)A relativistic neutrino background, or any other relativistic relic. ρ ∝ a⁻⁴.
The standard normalisation for N effectively-massless species is Ων = N · (7/8) · (4/11)^(4/3) · Ωγ, which massless_neutrinos applies for you.
Cosmic.NeutrinoDistribution — Type
NeutrinoDistributionThe momentum distribution f₀(q) (q = p/Tν in units of the present neutrino temperature) that a neutrino species is born with. The default is a Fermi–Dirac gas; a nonzero degeneracy parameter ξ = μ/T encodes a lepton asymmetry, and TabulatedNu carries an arbitrary numerically-specified f₀. Everything downstream — the background ρ, p and the free-streaming perturbation hierarchy — is built from `nuf0andnu_dlnf0`, so the distribution enters the physics in exactly one place.
Cosmic.Photons — Type
Photons(Ω_γ)The CMB. ρ ∝ a⁻⁴, w = 1/3. Construct from the CMB temperature with photons_from_Tcmb rather than guessing Ω_γ.
Cosmic.QuintessenceDE — Type
QuintessenceDE(Ω, lnρ, w_itp)Dark energy from a canonical scalar field rolling in a potential V(φ). The background Klein–Gordon equation is solved in cosmology() (with the potential amplitude shot to close the budget) and the resulting ρ(a), w(a) histories are carried here as interpolants in x = ln a.
Perturbations come for free and exactly: a canonical scalar field is precisely a fluid with rest-frame sound speed ĉs² = 1 (e.g. arXiv:1004.5509 §2), so the validated fld machinery in perturbations.jl — which picks up any non-Λ AbstractDarkEnergy with cs2de = 1 by default — evolves the exact quintessence perturbations with no Klein–Gordon perturbation block needed.
Cosmic.TabulatedNu — Type
TabulatedNu(f0, dlnf0)Arbitrary neutrino distribution given by callables f0(q) and its logarithmic derivative dlnf0(q) = dln f₀/dln q (non-thermal relics, sterile mixtures, …).
Cosmic.W0WaDarkEnergy — Type
W0WaDarkEnergy(Ω_de, w0, wa)CPL / Chevallier-Polarski-Linder parameterisation, w(a) = w0 + wa(1 - a). Integrating the continuity equation gives
ρ(a)/ρ₀ = a^(-3(1 + w0 + wa)) · exp(-3 wa (1 - a))Cosmic.degenerate_Neff_factor — Method
degenerate_Neff_factor(ξ)Radiation-density enhancement of a degenerate neutrino relative to ξ = 0, ρν(ξ)/ρν(0) = 1 + (30/7)(ξ/π)² + (15/7)(ξ/π)⁴ (exact for Fermi–Dirac). A single non-zero ξ therefore adds ΔN_eff = (this − 1) per affected species.
Cosmic.massive_neutrino — Method
massive_neutrino(m_eV, Tcmb, h; N_eff_share = 1.0, ξ = 0, dist = nothing)Build a massive neutrino species of mass m_eV.
N_eff_share is how much of Neff this species carries (1.0 for one of three standard neutrinos). It rescales the effective temperature by `Neffshare^(1/4)`, folding the non-instantaneous decoupling correction (Neff = 3.044, not 3) into a per-species temperature.
ξ is a degeneracy parameter (μ/T, a lepton asymmetry): it uses a FermiDirac(ξ) distribution and enhances the relativistic density by degenerate_Neff_factor(ξ). Pass a custom TabulatedNu as dist for a fully arbitrary phase space (then ξ is ignored).
Cosmic.massless_neutrinos — Method
Ων for `Neff` massless species given the photon density.
Cosmic.nu_ρ_integral — Function
nu_ρ_integral(y, dist = FermiDirac())The dimensionless energy integral
F(y) = ∫₀^∞ dx x² √(x² + y²) f₀(x), y = m c² / kT_ν(a),which controls how a massive neutrino's density evolves. For Fermi–Dirac with ξ = 0, F(0) = 7π⁴/120 ≈ 5.6822 (relativistic, ρ ∝ a⁻⁴) and F(y→∞) → y·(3/2)ζ(3) (ρ → m·n, ρ ∝ a⁻³). Neutrinos are the one component that crosses between the two, so no ρ ∝ a⁻ⁿ power law describes them. A generic dist (degenerate or tabulated) just replaces f₀.
Cosmic.warm_dark_matter — Method
warm_dark_matter(m_keV, Ω_wdm, Tcmb, h)A thermal warm-dark-matter relic: a fermion that froze out relativistic with two degrees of freedom at its own temperature Tw < Tν, cool enough to be all of (or part of) the dark matter today, warm enough that its residual free streaming erases small-scale structure. Exactly the same phase-space physics as a massive neutrino — the full momentum-resolved Boltzmann hierarchy — with the temperature ratio β = Tw/Tν fixed by the abundance:
Ω_wdm h² = β³ · m / (93.14 eV) ⇒ β = (Ω_wdm h² · 93.14 eV / m)^{1/3},the standard thermal-relic normalisation (the same one CLASS uses for its T_ncdm). Momenta are measured in units of Tw,0, so the distribution is a clean Fermi–Dirac and `y1 = m/Tw,0`; the relativistic density scales as β⁴.
The free-streaming cutoff this produces can be cross-checked against the Bode/Viel transfer-function fits — but here it is computed, not fitted.
Cosmic.ρ_over_ρc0 — Function
ρ_over_ρc0(s::Species, a)Energy density of s at scale factor a, in units of the critical density today. Every species must implement this.