1 unstable release
| 0.1.0 | Jan 26, 2026 |
|---|
#636 in Science
Used in 4 crates
44KB
737 lines
LambdaCDM-Rust
A high-precision, high-performance cosmology engine written in Rust.
This repository provides a modular ΛCDM toolkit:
lcdm-core: canonical parameter set, derived parameters, units, constants, neutrino modelinglcdm-background: expansion historyE(z),H(z), distances, root finding, basic numericslcdm-lss: large-scale structure utilities (growth factor/rate, power-spectrum helpers; HMF stubs)lcdm-boltzmann: Boltzmann-solver interface (trait + output container; backend implementations TBD)lcdm: the facade crate that re-exports everything and exposes an ergonomicprelude
Goals
- Strongly-typed units and a single “source of truth” for derived densities at z = 0
- Explicit neutrino modeling that avoids double counting (effective vs split)
- Deterministic, testable numerics (research-grade sanity checks like
E(0) = 1) - A clean layering: core → background → lss, with optional Boltzmann engines
Crate Overview
lcdm-core
Core definitions:
- Physical constants (AU, pc, c, G, σ, …)
- Strong unit newtypes:
Redshift,Mpc,KmPerSecMpc, … CosmoBuilder→ buildsScientificParamsDerivedParamsis the single source of truth for present-day physical densities
(ω ≡ Ω h²) and derived temperatures- Neutrino modeling:
NeutrinoSpec::Effective { n_eff, masses_ev }NeutrinoSpec::Split { n_ur, masses_ev, temp_factors }- Backend selection is done in
lcdm-background(analytic for strictly massless, table otherwise)
lcdm-background
Background expansion and distances:
Cosmology::e_z(z)returnsE(z) = H(z)/H0Cosmology::h_z(z)returnsH(z)inkm/s/Mpc- Distance observables:
- comoving radial distance
D_C(z) - comoving transverse distance
D_M(z)(curvature-aware) - luminosity distance
D_L(z) - angular diameter distance
D_A(z)
- comoving radial distance
- Simple bisection root finder and Simpson integrator for internal use
lcdm-lss
Large scale structure (LSS) helpers:
- Linear growth factor
D(z)and growth ratef(z)via RK45 integration inln(a) - Power spectrum interface:
- trait
PkProviderand helpersigma_r(currently a stub)
- trait
- Halo mass function module placeholder (Tinker08 stub)
lcdm-boltzmann
Boltzmann solver interface:
BoltzmannEnginetrait:fn compute(&self, params: &CanonicalParams, accuracy: AccuracyPreset) -> Result<BoltzmannOutput, String>;
BoltzmannOutputplaceholder fields (to be expanded with transfer functions, spectra, etc.)
lcdm (facade)
Single entry-point crate. Re-exports the sub-crates and provides lcdm::prelude::*.
Installation
Add the facade crate:
[dependencies]
lcdm = "0.1.0"
Or add sub-crates directly if you only need a specific layer (e.g., lcdm-core, lcdm-background).
Quick Start
use lcdm::prelude::*;
fn main() {
// Build a flat ΛCDM cosmology.
let cosmo = CosmoBuilder::new()
.flat()
.h(0.7)
.Omega_b(0.05)
.Omega_m(0.3)
.neutrino_effective(3.046, vec![0.0])
.build()
.unwrap();
// Construct the background model.
let model = Cosmology::new(cosmo);
// Expansion rate
let z = Redshift(1.0);
let ez = model.e_z(z);
println!("E(z=1) = {}", ez);
// Comoving distance
let dc = model.comoving_radial_distance(z).unwrap();
println!("D_C(z=1) = {} Mpc", dc.0);
}
Neutrino Models
Effective model (recommended)
Use when you want an N_eff-consistent thermal bath and a list of species masses (can include 0.0):
let params = CosmoBuilder::new()
.h(0.7)
.Omega_b(0.05)
.Omega_m(0.3)
.neutrino_effective(3.046, vec![0.0, 0.0, 0.0])
.flat()
.build()?;
- The code derives an effective neutrino temperature so that the total relativistic energy
density matches
n_eff, distributed across the provided species list.
Split model (CLASS-style)
Use when you want to separate massless (UR) from massive species explicitly:
let params = CosmoBuilder::new()
.h(0.7)
.Omega_b(0.05)
.Omega_m(0.3)
.neutrino_split(3.046, vec![0.06], vec![1.0])
.flat()
.build()?;
n_urmust be non-negativemasses_evandtemp_factorslengths must matchmasses_evmust be strictly > 0 (the builder rejects 0.0 masses in split mode)
Backend selection
When constructing lcdm_background::Cosmology, the neutrino backend is chosen automatically:
- Analytic backend if all masses are exactly
0.0(strict check) - Table backend otherwise (tabulated in
ln(a)and interpolated with PCHIP)
Accuracy Presets
Many numerical knobs are controlled by AccuracyPreset:
FastDefaultPrecisePaper
Example:
let params = CosmoBuilder::new()
.H0(70.0)
.Omega_b(0.05)
.Omega_m(0.3)
.neutrino_effective(3.046, vec![0.0, 0.0, 0.0])
.accuracy(AccuracyPreset::Precise)
.flat()
.build()?;
Examples
lcdm/examples/simple_usage.rs
Shows the typical facade usage (lcdm::prelude::*) and computes E(z) and D_C(z).
lcdm-background/examples/debug_e0.rs
Prints DerivedParams and checks:
- closure (sum of physical densities vs
h²) E(0) = 1- radiation scaling sanity checks at higher redshift
Run examples:
cargo run -p lcdm --example simple_usage
cargo run -p lcdm-background --example debug_e0
Testing
cargo test
The lcdm-background/tests/verification.rs suite includes:
H(z=0) == H0E(0) == 1with tight tolerances- consistency checks for
E(z)and closure - neutrino ratio checks for standard
N_eff = 3.046 - split-model input validation guards
Conventions and Units
- Physical densities are stored as ω ≡ Ω h² in
DerivedParams. Cosmology::e_z(z)computes: [ E(z)^2 = \frac{\sum_i \omega_i(z)}{h^2} ]- Distances are in Mpc.
H(z)is in km/s/Mpc.
Roadmap
- Implement
sigma_r(window function + k-integration) - Add concrete
PkProviderimplementations (from a Boltzmann engine and/or fitting formulas) - Fill in halo mass function and bias (Tinker08 and others)
- Expand
lcdm-boltzmannoutput structs for transfer functions / spectra - Optional: expose more observables (age of universe, sound horizon, growth with DE models, etc.)
License
Dependencies
~140KB