use crate::dynamics::Universe;
pub fn growth_factor(a: f64, universe: &Universe) -> f64 {
let n_steps = 1000;
let a_start = 0.001;
let da = (a - a_start) / n_steps as f64;
let mut d = Vec::new();
let mut d_prime = Vec::new();
d.push(a_start * a_start);
d_prime.push(2.0 * a_start);
for i in 1..=n_steps {
let a_i = a_start + i as f64 * da;
let h = universe.hubble_normalized(a_i);
let omega_m = 0.3111;
let d_curr = *d.last().unwrap();
let d_prime_curr = *d_prime.last().unwrap();
let d_next = d_curr + d_prime_curr * da;
let d_prime_next = d_prime_curr + (
-3.0 * d_prime_curr / a_i
+ 1.5 * omega_m * d_curr / (a_i * a_i * h * h)
) * da;
d.push(d_next);
d_prime.push(d_prime_next);
}
*d.last().unwrap() / growth_factor_at_unity(universe)
}
fn growth_factor_at_unity(universe: &Universe) -> f64 {
let n_steps = 1000;
let a_start = 0.001;
let da = (1.0 - a_start) / n_steps as f64;
let mut d = Vec::new();
let mut d_prime = Vec::new();
d.push(a_start * a_start);
d_prime.push(2.0 * a_start);
for i in 1..=n_steps {
let a_i = a_start + i as f64 * da;
let h = universe.hubble_normalized(a_i);
let omega_m = 0.3111;
let d_curr = *d.last().unwrap();
let d_prime_curr = *d_prime.last().unwrap();
let d_next = d_curr + d_prime_curr * da;
let d_prime_next = d_prime_curr + (
-3.0 * d_prime_curr / a_i
+ 1.5 * omega_m * d_curr / (a_i * a_i * h * h)
) * da;
d.push(d_next);
d_prime.push(d_prime_next);
}
*d.last().unwrap()
}
pub fn growth_rate(a: f64, universe: &Universe) -> f64 {
let da = 0.001 * a;
let d_plus = growth_factor(a + da, universe);
let d_minus = growth_factor(a - da, universe);
(a / growth_factor(a, universe)) * (d_plus - d_minus) / (2.0 * da)
}
#[cfg(test)]
mod tests {
use super::*;
use approx::assert_relative_eq;
#[test]
fn test_growth_normalized() {
let universe = crate::dynamics::Universe::benchmark();
let d = growth_factor(1.0, &universe);
assert_relative_eq!(d, 1.0, epsilon = 0.1);
}
#[test]
fn test_growth_scaling() {
let universe = crate::dynamics::Universe::einstein_de_sitter(70.0);
let d1 = growth_factor(0.5, &universe);
let d2 = growth_factor(1.0, &universe);
assert!(d2 > d1);
assert!(d2 / d1 > 1.0);
}
}