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::domain::common::constants::{EARTH_RADIUS, R_GAS, SIGMA_SB};
use sciforge::hub::domain::physics::thermodynamics::clausius_clapeyron;
use sciforge::hub::prelude::constants::elements::atomic_mass;
pub const OCEAN_SURFACE_AREA_M2: f64 = 3.61e14;
pub const MEAN_OCEAN_DEPTH_M: f64 = 3688.0;
pub const OCEAN_VOLUME_M3: f64 = 1.335e18;
pub const MEAN_SALINITY_PSU: f64 = 35.0;
pub const SEAWATER_DENSITY: f64 = 1025.0;
pub struct OceanLayer {
    pub name: &'static str,
    pub depth_range_m: (f64, f64),
    pub mean_temperature_c: f64,
    pub mean_salinity_psu: f64,
}
impl OceanLayer {
    pub fn density_kg_m3(&self) -> f64 {
        let t = self.mean_temperature_c;
        let s = self.mean_salinity_psu;
        999.842594 + 6.793952e-2 * t - 9.095290e-3 * t * t + 1.001685e-4 * t * t * t + 0.824493 * s
            - 4.0899e-3 * t * s
    }
    pub fn pressure_at_depth(&self, depth_m: f64) -> f64 {
        SEAWATER_DENSITY * *crate::SURFACE_GRAVITY * depth_m
    }
    pub fn sound_speed_m_s(&self) -> f64 {
        let t = self.mean_temperature_c;
        let s = self.mean_salinity_psu;
        let d = (self.depth_range_m.0 + self.depth_range_m.1) / 2.0;
        1449.2 + 4.6 * t - 0.055 * t * t
            + 0.00029 * t * t * t
            + (1.34 - 0.01 * t) * (s - 35.0)
            + 0.016 * d
    }
}
pub fn surface_mixed_layer() -> OceanLayer {
    OceanLayer {
        name: "Surface Mixed Layer",
        depth_range_m: (0.0, 200.0),
        mean_temperature_c: 17.0,
        mean_salinity_psu: 35.0,
    }
}
pub fn thermocline() -> OceanLayer {
    OceanLayer {
        name: "Thermocline",
        depth_range_m: (200.0, 1000.0),
        mean_temperature_c: 8.0,
        mean_salinity_psu: 34.8,
    }
}
pub fn deep_ocean() -> OceanLayer {
    OceanLayer {
        name: "Deep Ocean",
        depth_range_m: (1000.0, 4000.0),
        mean_temperature_c: 2.0,
        mean_salinity_psu: 34.7,
    }
}
pub fn thermohaline_overturning_rate_sv() -> f64 {
    17.0
}
pub fn ocean_heat_content_j(temp_anomaly_k: f64, depth_m: f64) -> f64 {
    SEAWATER_DENSITY * crate::CP_SEAWATER * OCEAN_SURFACE_AREA_M2 * depth_m * temp_anomaly_k
}
pub fn sea_level_rise_thermal_m(temp_anomaly_k: f64, depth_m: f64) -> f64 {
    let expansion_coeff = 2.0e-4;
    expansion_coeff * temp_anomaly_k * depth_m
}
pub fn surface_longwave_radiation_w_m2(sst_c: f64, emissivity: f64) -> f64 {
    let t_k = sst_c + crate::CELSIUS_TO_KELVIN;
    emissivity * SIGMA_SB * t_k.powi(4)
}
pub fn ocean_area_from_fraction(fraction: f64) -> f64 {
    4.0 * std::f64::consts::PI * EARTH_RADIUS * EARTH_RADIUS * fraction
}
pub fn vapor_pressure_over_ocean(sst_c: f64) -> f64 {
    let p_ref = crate::VAPOR_PRESSURE_0C;
    let t_ref = crate::CELSIUS_TO_KELVIN;
    let t2 = sst_c + crate::CELSIUS_TO_KELVIN;
    let l_vap = *crate::L_VAPORIZATION;
    clausius_clapeyron(p_ref, t_ref, t2, l_vap)
}
pub fn dissolved_gas_henry(
    partial_pressure_pa: f64,
    temperature_c: f64,
    henry_const_mol_m3_pa: f64,
) -> f64 {
    let t_k = temperature_c + crate::CELSIUS_TO_KELVIN;
    let correction = (-2400.0 * (1.0 / t_k - 1.0 / 298.15) / R_GAS).exp();
    henry_const_mol_m3_pa * partial_pressure_pa * correction
}
pub fn nacl_molar_mass() -> f64 {
    (atomic_mass(11) + atomic_mass(17)) * 1e-3
}
pub fn nacl_molality_35psu() -> f64 {
    0.035 / nacl_molar_mass()
}