jupiters 0.0.3

Jupiter celestial simulation crate for the MilkyWay SolarSystem workspace
Documentation
use sciforge::hub::domain::meteorology::radiation::{solar_constant, stefan_boltzmann_flux};
use sciforge::hub::prelude::constants::R_GAS;

pub const ONEBARPRESSURE: f64 = crate::ONEBARPRESSURE;
pub const ONEBARTEMPK: f64 = crate::ONEBARTEMPK;

pub fn atmospheremolarmass() -> f64 {
    crate::matmosphere()
}

pub const LAPSERATETROPOSPHERE: f64 = 0.002;

pub struct AtmosphericLayer {
    pub name: &'static str,
    pub basealtitudem: f64,
    pub topaltitudem: f64,
    pub basetemperaturek: f64,
    pub lapseratekperm: f64,
}

impl AtmosphericLayer {
    pub fn temperatureat(&self, altitudem: f64) -> f64 {
        let h = (altitudem - self.basealtitudem)
            .max(0.0)
            .min(self.topaltitudem - self.basealtitudem);
        self.basetemperaturek - self.lapseratekperm * h
    }

    pub fn pressureat(&self, altitudem: f64) -> f64 {
        let t = self.temperatureat(altitudem);
        let h = altitudem - self.basealtitudem;
        let g0 = *crate::SURFACEGRAVITY;
        if self.lapseratekperm.abs() < 1e-10 {
            let pbase = barometricpressure(self.basealtitudem);
            pbase * (-g0 * atmospheremolarmass() * h / (R_GAS * self.basetemperaturek)).exp()
        } else {
            let pbase = barometricpressure(self.basealtitudem);
            pbase
                * (t / self.basetemperaturek)
                    .powf(g0 * atmospheremolarmass() / (R_GAS * self.lapseratekperm))
        }
    }

    pub fn densityat(&self, altitudem: f64) -> f64 {
        let p = self.pressureat(altitudem);
        let t = self.temperatureat(altitudem);
        p * atmospheremolarmass() / (R_GAS * t)
    }
}

pub fn troposphere() -> AtmosphericLayer {
    AtmosphericLayer {
        name: "Troposphere",
        basealtitudem: 0.0,
        topaltitudem: 50000.0,
        basetemperaturek: 165.0,
        lapseratekperm: 0.002,
    }
}

pub fn stratosphere() -> AtmosphericLayer {
    AtmosphericLayer {
        name: "Stratosphere",
        basealtitudem: 50000.0,
        topaltitudem: 320000.0,
        basetemperaturek: 110.0,
        lapseratekperm: -0.0003,
    }
}

pub fn thermosphere() -> AtmosphericLayer {
    AtmosphericLayer {
        name: "Thermosphere",
        basealtitudem: 320000.0,
        topaltitudem: 1000000.0,
        basetemperaturek: 190.0,
        lapseratekperm: -0.0008,
    }
}

pub fn barometricpressure(altitudem: f64) -> f64 {
    let g0 = *crate::SURFACEGRAVITY;
    if altitudem <= 50000.0 {
        let t = ONEBARTEMPK - LAPSERATETROPOSPHERE * altitudem;
        ONEBARPRESSURE
            * (t / ONEBARTEMPK).powf(g0 * atmospheremolarmass() / (R_GAS * LAPSERATETROPOSPHERE))
    } else {
        let ptropo = barometricpressure(50000.0);
        let ttropo = 110.0;
        ptropo * (-g0 * atmospheremolarmass() * (altitudem - 50000.0) / (R_GAS * ttropo)).exp()
    }
}

pub fn scaleheight() -> f64 {
    *crate::SCALEHEIGHT
}

pub fn meansolarirradiance() -> f64 {
    solar_constant() / (5.2044 * 5.2044)
}

pub fn effectivetemp() -> f64 {
    let flux = meansolarirradiance() * (1.0 - crate::BONDALBEDO) / 4.0 + crate::INTERNALHEATINGWM2;
    (flux / sciforge::hub::prelude::constants::SIGMA_SB).powf(0.25)
}

pub fn olr() -> f64 {
    stefan_boltzmann_flux(crate::ONEBARTEMPK)
}