primat.weak_rates.api — n↔p weak rates¶
weak_rates.api — public n<->p weak-rate entry points¶
Top-level functions used by the rest of primat (mainly
primat.background): ComputeWeakRates() (raw computation),
InterpolateWeakRates() (load the fingerprinted on-disk cache without
recomputing), and RecomputeWeakRates() (the usual entry point: load the
cache if the fingerprint matches, else recompute and write it).
Normalisation: the stored rates are in units of 1/tau_n rather than absolute
s^-1 (Phys. Rep. Eqs. 89-91) — the caller multiplies by 1/cfg.tau_n (or by
the analytically computed K/Fn) after loading; see
weak_rates.corrections.ComputeFn() for the free-neutron-decay
phase-space normalisation Fn.
- primat.weak_rates.api.ComputeWeakRates(Tvec, cfg, dFDneu_func=None, dFDneu_moments=None)[source]¶
Compute the non-thermal n↔p weak rate tables over the BBN T range.
Evaluates the forward rate Γ_{n→p}(T) and backward rate Γ_{p→n}(T) on the photon-temperature grid Tg_vec, by summing the additive correction terms (controlled by the cfg flags) returned by
_correction_terms():Γ_{n→p} = K × [ (CCR or Born) (+ FMCCR/FMNoCCR) (+ SD_CCR/SD) (+ SD_FMCCR/SD_FM) ]
The finite-temperature CCRTh correction is NOT included here — it is stored separately (
nTOp_thermal_<hash>.txt) and recombined at point of use inRecomputeWeakRates()via_thermal_correction_interpolants().where:
_L_BORN — Born rate ∫ p² [χ₊(E)+χ₊(−E)] dp (Phys. Rep. Eqs. 77–78). Active when cfg.radiative_corrections=False. _L_CCR — Born integrand × FermiCoulomb × RadCorrResum (T=0 Coulomb + resummed radiative corrections; Phys. Rep. Eq. 101). Active when cfg.radiative_corrections=True (replaces Born). _L_FMCCR — Finite-nucleon-mass correction × Coulomb × radiative (Fokker-Planck expansion; Phys. Rep. §III.G). Active when cfg.finite_mass_corrections=True and cfg.radiative_corrections=True. _L_FMNoCCR — Finite-nucleon-mass correction without Coulomb/radiative. Active when cfg.finite_mass_corrections=True and cfg.radiative_corrections=False. (_L_CCRTh — Finite-temperature radiative corrections (Brown & Sawyer 2001; Phys. Rep. §III.H, Eqs. 107–113) are NOT summed here; they are built separately by _thermal_correction_interpolants and added in RecomputeWeakRates.) _L_SD — Born-level spectral-distortion correction (deviation of f_ν from Fermi–Dirac, passed in via dFDneu_func). Active when dFDneu_func is supplied and cfg.radiative_corrections=False. _L_SD_CCR — Same with Coulomb × radiative factor. Active when dFDneu_func is supplied and cfg.radiative_corrections=True. _L_SD_FMNoCCR — SD-FM: finite-nucleon-mass correction applied to the spectral-distortion deviation instead of the plain Fermi-Dirac (generate_rates/PRIMAT-Main-gray.m's δχFM). Active when dFDneu_moments is supplied (i.e. cfg.analytic_distortions=True), cfg.finite_mass_corrections =True and cfg.radiative_corrections=False. _L_SD_FMCCR — Same with Coulomb × radiative factor. Active when dFDneu_moments is supplied, cfg.finite_mass_corrections= True and cfg.radiative_corrections=True.The overall rate constant K is normalised via the neutron lifetime:
K = 1 / (τ_n × Fn) (Phys. Rep. Eq. 89–91)
where Fn = ComputeFn(cfg) is the free-decay phase-space integral.
- Parameters:
Tvec (list [Tg_vec, Tnu_vec], both float arrays in Kelvin (as output) – by PRIMAT._setup_background_and_cosmo).
cfg (PRIMATConfig instance.)
dFDneu_func (callable or None.) –
If provided, adds the spectral-distortion correction _L_SD. Signature:
dFDneu_func(en, x, znu, sgnq) → float
where en = E/mₑ, x = mₑ/(kB Tγ), znu = mₑ/(kB Tν), sgnq = ±1. Must encode the sign convention for blocking factors (en < 0), as described in PRIMAT._setup_background_and_cosmo.
dFDneu_moments (dict or None.) – If provided (only in analytic-distortion mode – see neutrino_history.AnalyticDistortion.dFDneu_moments), adds the SD-FM correction (_L_SD_FMCCR/_L_SD_FMNoCCR) on top of the SD correction above, when cfg.finite_mass_corrections is also True.
- Returns:
[T_all, frwrd, bkwrd] (list) – T_all — 1-D float array, photon temperatures in Kelvin. frwrd — 1-D float array, non-thermal Γ_{n→p}(T) in units of 1/τ_n. bkwrd — 1-D float array, non-thermal Γ_{p→n}(T) in units of 1/τ_n.
Example – >>> rates = ComputeWeakRates([Tg_vec, Tnu_vec], cfg) >>> T_K, lam_nTOp, lam_pTOn = rates
- primat.weak_rates.api.InterpolateWeakRates(cfg)[source]¶
Load n↔p weak rates from the hash-named cache file and return interpolants.
Reads
rates/weak/nTOp_<hash>.txt(three columns: T in Kelvin, Gamma_{n→p} in units of 1/tau_n, Gamma_{p→n} in units of 1/tau_n) where<hash>is the 16-hex fingerprint of the current configuration. Raises FileNotFoundError if the file does not exist (it has not been computed yet for this configuration).- Parameters:
cfg – PRIMATConfig instance (provides _resolved_data_dir).
- Returns:
[frwrd, bkwrd] –
- two scipy interp1d objects (extrapolating), each mapping
T in Kelvin → rate in units of 1/tau_n.
- primat.weak_rates.api.RecomputeWeakRates(Tvec, cfg, dFDneu_func=None, dFDneu_moments=None)[source]¶
Load the n<->p weak-rate tables from the fingerprinted cache, or recompute.
Implements the cache-loading logic for the non-thermal rate (the thermal CCRTh correction is always handled separately, see step 5):
Compute the fingerprint hash of the current configuration (
_weak_rate_fingerprint()).If cfg.weak_rate_cache is True and rates/weak/nTOp_<hash>.txt exists with a matching fingerprint_hash header, load and interpolate it directly (cheap: no integration at all).
Otherwise call
ComputeWeakRates()to recompute from scratch (~2 s). If cfg.save_nTOp is True, save the new data and the current fingerprint header to that file.Forced recompute: if cfg.spectral_distortions and cfg.analytic_distortions, the cache is bypassed entirely (never loaded, never written). Analytic distortions are continuous knobs (y_SZ, y_gray) typically scanned point-by-point in an MCMC; caching them would write one file per parameter point and pollute rates/weak/. The same rule applies to any future user-supplied dFDneu_func that cannot be fingerprinted.
Build the finite-temperature CCRTh correction with
_thermal_correction_interpolants()(its ownnTOp_thermal_<hash>.txtcache) and add it to the non-thermal interpolant from step 2/3. The returned rate is the sum of the two.
cfg.tau_n_normalization/cfg.tau_ndo not enter the fingerprint: the stored rates are in units of 1/τ_n (Fn already applied inside ComputeWeakRates), so they need only multiplying by 1/tau_n after loading — the cached values themselves are tau_n-independent.The hash is embedded in the filename (
nTOp_<hash>.txt), so different configurations coexist inrates/weak/without overwriting each other.cfg.save_nTOpdefaults to True: every newly computed configuration is saved automatically so subsequent runs reuse it without recomputing.- Parameters:
Tvec ([Tg_vec, Tnu_vec] (arrays in MeV))
cfg (PRIMATConfig)
dFDneu_func (callable or None — spectral-distortion correction function;) – forwarded to ComputeWeakRates on a cache miss.
dFDneu_moments (dict or None — energy-moment functions of dFDneu_func) – (analytic-distortion mode only); forwarded to ComputeWeakRates on a cache miss to enable the SD-FM term.
- Returns:
[frwrd, bkwrd] (two callables (n->p and p->n) T[K] -> rate in units of)
1/τ_n, covering the whole BBN temperature range. Each is the sum of the
stored non-thermal interpolant (Born+FM+CCR+SD) and the separately-cached
finite-temperature correction (CCRTh), so multiplying by 1/τ_n gives the
full physical rate in s⁻¹.