earths 0.0.1

High-fidelity Earth simulation engine — orbit, atmosphere, geology, hydrology, biosphere, terrain, lighting, rendering, satellites, and temporal systems with full scientific coupling
Documentation
use sciforge::hub::prelude::biology::population::logistic_growth;
pub struct Population {
    pub species_name: &'static str,
    pub count: f64,
    pub carrying_capacity: f64,
    pub intrinsic_growth_rate: f64,
    pub body_mass_kg: f64,
}
impl Population {
    pub fn growth_rate(&self) -> f64 {
        logistic_growth(
            self.intrinsic_growth_rate,
            self.count,
            self.carrying_capacity,
        )
    }
    pub fn project_forward(&self, dt_years: f64) -> f64 {
        let r = self.intrinsic_growth_rate;
        let k = self.carrying_capacity;
        let n = self.count;
        k / (1.0 + ((k - n) / n) * (-r * dt_years).exp())
    }
    pub fn metabolic_rate_w(&self) -> f64 {
        crate::KLEIBER_A * self.body_mass_kg.powf(0.75)
    }
    pub fn home_range_km2(&self) -> f64 {
        crate::MCNAB_A * self.body_mass_kg.powf(1.0)
    }
    pub fn generation_time_years(&self) -> f64 {
        crate::GEN_TIME_A * self.body_mass_kg.powf(0.25)
    }
    pub fn max_lifespan_years(&self) -> f64 {
        crate::LIFESPAN_A * self.body_mass_kg.powf(0.20)
    }
}
pub struct PredatorPrey {
    pub prey: Population,
    pub predator: Population,
    pub attack_rate: f64,
    pub conversion_efficiency: f64,
    pub predator_death_rate: f64,
}
impl PredatorPrey {
    pub fn prey_growth_rate(&self) -> f64 {
        let prey_logistic = self.prey.growth_rate();
        let predation = self.attack_rate * self.prey.count * self.predator.count;
        prey_logistic - predation
    }
    pub fn predator_growth_rate(&self) -> f64 {
        let births =
            self.conversion_efficiency * self.attack_rate * self.prey.count * self.predator.count;
        let deaths = self.predator_death_rate * self.predator.count;
        births - deaths
    }
    pub fn step(&mut self, dt: f64) {
        let (n, p) = (self.prey.count, self.predator.count);
        let deriv = |prey: f64, pred: f64| -> (f64, f64) {
            let prey_logistic =
                self.prey.intrinsic_growth_rate * prey * (1.0 - prey / self.prey.carrying_capacity);
            let predation = self.attack_rate * prey * pred;
            let dn = prey_logistic - predation;
            let dp = self.conversion_efficiency * self.attack_rate * prey * pred
                - self.predator_death_rate * pred;
            (dn, dp)
        };
        let (k1n, k1p) = deriv(n, p);
        let (k2n, k2p) = deriv(n + 0.5 * dt * k1n, p + 0.5 * dt * k1p);
        let (k3n, k3p) = deriv(n + 0.5 * dt * k2n, p + 0.5 * dt * k2p);
        let (k4n, k4p) = deriv(n + dt * k3n, p + dt * k3p);
        self.prey.count = (n + dt / 6.0 * (k1n + 2.0 * k2n + 2.0 * k3n + k4n)).max(0.0);
        self.predator.count = (p + dt / 6.0 * (k1p + 2.0 * k2p + 2.0 * k3p + k4p)).max(0.0);
    }
}
pub fn african_elephant() -> Population {
    Population {
        species_name: "African Elephant",
        count: 415_000.0,
        carrying_capacity: 1_000_000.0,
        intrinsic_growth_rate: 0.05,
        body_mass_kg: 6000.0,
    }
}
pub fn blue_whale() -> Population {
    Population {
        species_name: "Blue Whale",
        count: 25_000.0,
        carrying_capacity: 350_000.0,
        intrinsic_growth_rate: 0.04,
        body_mass_kg: 150_000.0,
    }
}