earths 0.0.4

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 speciesname: &'static str,
    pub count: f64,
    pub carryingcapacity: f64,
    pub intrinsicgrowthrate: f64,
    pub bodymasskg: f64,
}
impl Population {
    pub fn growthrate(&self) -> f64 {
        logistic_growth(self.intrinsicgrowthrate, self.count, self.carryingcapacity)
    }
    pub fn projectforward(&self, dtyears: f64) -> f64 {
        let r = self.intrinsicgrowthrate;
        let k = self.carryingcapacity;
        let n = self.count;
        k / (1.0 + ((k - n) / n) * (-r * dtyears).exp())
    }
    pub fn metabolicratew(&self) -> f64 {
        crate::KLEIBERA * self.bodymasskg.powf(0.75)
    }
    pub fn homerangekm2(&self) -> f64 {
        crate::MCNABA * self.bodymasskg.powf(1.0)
    }
    pub fn generationtimeyears(&self) -> f64 {
        crate::GENTIMEA * self.bodymasskg.powf(0.25)
    }
    pub fn maxlifespanyears(&self) -> f64 {
        crate::LIFESPANA * self.bodymasskg.powf(0.20)
    }
}
pub struct PredatorPrey {
    pub prey: Population,
    pub predator: Population,
    pub attackrate: f64,
    pub conversionefficiency: f64,
    pub predatordeathrate: f64,
}
impl PredatorPrey {
    pub fn preygrowthrate(&self) -> f64 {
        let preylogistic = self.prey.growthrate();
        let predation = self.attackrate * self.prey.count * self.predator.count;
        preylogistic - predation
    }
    pub fn predatorgrowthrate(&self) -> f64 {
        let births =
            self.conversionefficiency * self.attackrate * self.prey.count * self.predator.count;
        let deaths = self.predatordeathrate * 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 preylogistic =
                self.prey.intrinsicgrowthrate * prey * (1.0 - prey / self.prey.carryingcapacity);
            let predation = self.attackrate * prey * pred;
            let dn = preylogistic - predation;
            let dp = self.conversionefficiency * self.attackrate * prey * pred
                - self.predatordeathrate * 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 africanelephant() -> Population {
    Population {
        speciesname: "African Elephant",
        count: 415000.0,
        carryingcapacity: 1000000.0,
        intrinsicgrowthrate: 0.05,
        bodymasskg: 6000.0,
    }
}
pub fn bluewhale() -> Population {
    Population {
        speciesname: "Blue Whale",
        count: 25000.0,
        carryingcapacity: 350000.0,
        intrinsicgrowthrate: 0.04,
        bodymasskg: 150000.0,
    }
}