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 earth::atmosphere::climate::{
    CLIMATE_SENSITIVITY_K, ClimateState, EARTH_ALBEDO, PRE_INDUSTRIAL_CO2_PPM,
    co2_doubling_forcing, planck_spectral_radiance, solar_zenith,
};
use earth::atmosphere::heatwaves::{HeatWave, dew_point_c, saturation_vapor_pressure_pa};
use earth::atmosphere::layers::{
    LAPSE_RATE_TROPOSPHERE, SEA_LEVEL_PRESSURE, SEA_LEVEL_TEMPERATURE, barometric_pressure,
    dry_air_molar_mass, mesosphere, scale_height, stratosphere, thermosphere, troposphere,
};
use earth::atmosphere::storms::{TropicalCyclone, cape_integrated, cape_layer, fujita_scale};
use earth::atmosphere::winds::{
    OMEGA_EARTH, beaufort_to_m_s, coriolis_parameter, ekman_spiral_depth, geostrophic_wind_speed,
    gradient_wind_speed, thermal_wind_shear, wind_chill_temperature,
};
use earth::hydrology::glaciers::{
    GLEN_FLOW_LAW_A, ICE_CREEP_EXPONENT, antarctic_ice_sheet, greenland_ice_sheet, ice_density,
    ice_rheology_viscosity,
};
use earth::hydrology::lakes::{baikal, superior};
use earth::hydrology::oceans::{
    MEAN_OCEAN_DEPTH_M, MEAN_SALINITY_PSU, OCEAN_SURFACE_AREA_M2, OCEAN_VOLUME_M3,
    SEAWATER_DENSITY, deep_ocean, dissolved_gas_henry, ocean_area_from_fraction,
    ocean_heat_content_j, sea_level_rise_thermal_m, surface_longwave_radiation_w_m2,
    surface_mixed_layer, thermocline, thermohaline_overturning_rate_sv, vapor_pressure_over_ocean,
};
use earth::hydrology::rivers::{amazon, chezy_velocity, hjulstrom_erosion_threshold, nile};

fn main() {
    let tropo = troposphere();
    let strato = stratosphere();
    let meso = mesosphere();
    let thermo = thermosphere();

    let altitudes = [0.0, 5000.0, 11000.0, 20000.0, 50000.0, 80000.0];
    let mut total_density = 0.0;
    for &alt in &altitudes {
        let layer = if alt < 12_000.0 {
            &tropo
        } else if alt < 50_000.0 {
            &strato
        } else if alt < 85_000.0 {
            &meso
        } else {
            &thermo
        };
        let temp = layer.temperature_at(alt);
        let press = layer.pressure_at(alt);
        let dens = layer.density_at(alt);
        total_density += dens;
        println!(
            "[{:>12}] alt={:>6.0}m  T={:.1}K  P={:.0}Pa  ρ={:.4}kg/m³",
            layer.name, alt, temp, press, dens
        );
    }

    let p_sea = barometric_pressure(0.0);
    let p_cruise = barometric_pressure(10_000.0);
    let h_scale = scale_height();
    println!(
        "P(sea)={:.0}Pa  P(10km)={:.0}Pa  H_scale={:.0}m  Σρ={:.4}",
        p_sea, p_cruise, h_scale, total_density
    );
    println!(
        "constants: P0={} T0={} M_air={} Γ={}",
        SEA_LEVEL_PRESSURE,
        SEA_LEVEL_TEMPERATURE,
        dry_air_molar_mass(),
        LAPSE_RATE_TROPOSPHERE
    );

    let pre_ind = ClimateState::pre_industrial();
    let current = ClimateState::current();

    let forcing_pi = pre_ind.co2_radiative_forcing();
    let forcing_now = current.co2_radiative_forcing();
    let warming = current.equilibrium_warming();
    let olr = current.outgoing_longwave_radiation();
    let asr = current.absorbed_solar_radiation();
    let imbalance = current.energy_imbalance();
    let t_eff = current.effective_emission_temperature();
    let greenhouse = current.greenhouse_effect_k();

    println!(
        "CO2: pre-ind={:.0}ppm  now={:.0}ppm",
        pre_ind.co2_ppm, current.co2_ppm
    );
    println!(
        "Forcing: pi={:.2} now={:.2} W/m²  warming={:.2}K",
        forcing_pi, forcing_now, warming
    );
    println!(
        "OLR={:.1}  ASR={:.1}  imbalance={:.2}  T_eff={:.1}K  greenhouse={:.1}K",
        olr, asr, imbalance, t_eff, greenhouse
    );

    let zenith = solar_zenith(45.0, 23.44, 0.0);
    let radiance = planck_spectral_radiance(10e-6, 288.0);
    let doubling = co2_doubling_forcing();
    println!(
        "zenith={:.2}°  planck(10µm,288K)={:.4}  2xCO2={:.2}W/m²",
        zenith, radiance, doubling
    );
    println!(
        "constants: CO2_PI={} sensitivity={} albedo={}",
        PRE_INDUSTRIAL_CO2_PPM, CLIMATE_SENSITIVITY_K, EARTH_ALBEDO
    );

    let cyclone = TropicalCyclone {
        max_sustained_wind_m_s: 75.0,
        central_pressure_hpa: 940.0,
        radius_max_wind_km: 30.0,
        latitude_deg: 20.0,
    };
    let cat = cyclone.saffir_simpson_category();
    let ace = cyclone.accumulated_cyclone_energy(48.0);
    let pi = TropicalCyclone::potential_intensity_m_s(302.0, 200.0, 1500.0);
    let rossby = cyclone.rossby_deformation_radius();
    let wind_r = cyclone.wind_at_radius(60.0);
    let fujita = fujita_scale(90.0);
    let cape_single = cape_layer(305.0, 300.0, 1000.0);
    let cape = cape_integrated(305.0, 300.0, 0.0075, 500.0, 40);
    println!(
        "Cyclone: cat={} ACE={:.1} PI={:.1}m/s Rossby={:.0}m wind@60km={:.1}m/s",
        cat, ace, pi, rossby, wind_r
    );
    println!(
        "Fujita(90m/s)={} CAPE_layer={:.1} CAPE_integrated={:.1}J/kg",
        fujita, cape_single, cape
    );

    let f_45 = coriolis_parameter(45.0);
    let vg = geostrophic_wind_speed(0.01, 45.0, 1.225);
    let vgr = gradient_wind_speed(0.01, 500_000.0, 45.0, 1.225);
    let tw = thermal_wind_shear(5e-6, 260.0, 45.0, 500e2, 750e2);
    let ekman = ekman_spiral_depth(0.05, 45.0);
    let b7 = beaufort_to_m_s(7);
    let wc = wind_chill_temperature(-10.0, 30.0);
    println!(
        "ω={:.5e}  f(45°)={:.5e}  Vg={:.1}  Vgr={:.1}  thermal_wind={:.4}",
        OMEGA_EARTH, f_45, vg, vgr, tw
    );
    println!(
        "Ekman={:.0}m  B7={:.1}m/s  windchill(-10°,30km/h)={:.1}°C",
        ekman, b7, wc
    );

    let hw = HeatWave {
        max_temperature_c: 45.0,
        duration_days: 5,
        relative_humidity_percent: 40.0,
    };
    let hi = hw.heat_index_c();
    let wb = hw.wet_bulb_temperature_c();
    let danger = hw.danger_level();
    let mort = hw.excess_mortality_factor();
    let svp = saturation_vapor_pressure_pa(35.0);
    let dp = dew_point_c(35.0, 60.0);
    println!(
        "Heatwave: HI={:.1}°C  Tw={:.1}°C  danger={}  mortality_factor={:.2}",
        hi, wb, danger, mort
    );
    println!("SVP(35°C)={:.0}Pa  dewpoint(35°C,60%)={:.1}°C", svp, dp);

    let sml = surface_mixed_layer();
    let tc = thermocline();
    let deep = deep_ocean();
    let rho_sml = sml.density_kg_m3();
    let rho_tc = tc.density_kg_m3();
    let rho_deep = deep.density_kg_m3();
    let speed_sml = sml.sound_speed_m_s();
    let p_deep = deep.pressure_at_depth(3000.0);
    let thc = thermohaline_overturning_rate_sv();
    let ohc = ocean_heat_content_j(0.5, 700.0);
    let slr = sea_level_rise_thermal_m(0.5, 700.0);
    let lw = surface_longwave_radiation_w_m2(17.0, 0.97);
    let oa = ocean_area_from_fraction(0.71);
    let vp = vapor_pressure_over_ocean(20.0);
    let co2_dissolved = dissolved_gas_henry(40.0, 15.0, 3.4e-4);
    println!(
        "Ocean: ρ_sml={:.1} ρ_tc={:.1} ρ_deep={:.1}  sound={:.0}m/s  P@3km={:.0}Pa",
        rho_sml, rho_tc, rho_deep, speed_sml, p_deep
    );
    println!(
        "THC={:.0}Sv  OHC={:.2e}J  SLR={:.4}m  LW={:.1}W/m²",
        thc, ohc, slr, lw
    );
    println!(
        "area(0.71)={:.2e}m²  VP(20°C)={:.0}Pa  CO2_diss={:.6}mol/m³",
        oa, vp, co2_dissolved
    );
    println!(
        "constants: A={:.2e}m²  D={:.0}m  V={:.3e}m³  S={:.0}psu  ρ={:.0}",
        OCEAN_SURFACE_AREA_M2,
        MEAN_OCEAN_DEPTH_M,
        OCEAN_VOLUME_M3,
        MEAN_SALINITY_PSU,
        SEAWATER_DENSITY
    );

    let am = amazon();
    let ni = nile();
    let v_manning = am.manning_velocity(3.0, 0.035);
    let fr = am.froude_number(1.5, 10.0);
    let re = ni.reynolds_number(1.0, 5.0);
    let sed = am.sediment_transport_capacity(1.5, 10.0, 0.001);
    let sp = am.stream_power_w_per_m();
    let sd = ni.specific_discharge_m_s();
    let chezy = chezy_velocity(50.0, 2.0, 0.001);
    let hjul = hjulstrom_erosion_threshold(0.5);
    println!(
        "Amazon: V_manning={:.2}m/s  Fr={:.3}  sed={:.4}  SP={:.0}W/m",
        v_manning, fr, sed, sp
    );
    println!(
        "Nile: Re={:.0}  q={:.2e}m/s  Chézy={:.2}m/s  Hjul(0.5mm)={:.3}m/s",
        re, sd, chezy, hjul
    );

    let bk = baikal();
    let su = superior();
    let d_bk = bk.mean_depth_m();
    let sdl = su.shoreline_development_ratio(4385.0);
    let rt = bk.residence_time_years(330.0);
    let strat = su.thermal_stratification_energy_j(18.0, 4.0);
    let evap = su.evaporation_rate_mm_day(25.0, 18.0, 3.0, 60.0);
    let lw_lake = bk.longwave_radiation_w_m2(4.0, 0.97);
    println!(
        "Baikal: mean_d={:.1}m  res_time={:.0}yr  LW={:.1}W/m²",
        d_bk, rt, lw_lake
    );
    println!(
        "Superior: SDL={:.2}  strat_E={:.2e}J  evap={:.2}mm/d",
        sdl, strat, evap
    );

    let ant = antarctic_ice_sheet();
    let grl = greenland_ice_sheet();
    let mb_ant = ant.mass_balance_m_yr();
    let tau_ant = ant.basal_shear_stress_pa();
    let vel_ant = ant.deformation_velocity_m_yr();
    let ela = grl.equilibrium_line_altitude(0.0);
    let vol = grl.volume_m3(800_000.0);
    let sle = grl.sea_level_equivalent_mm(800_000.0);
    let visc = ice_rheology_viscosity(-10.0, 100_000.0);
    println!(
        "Antarctic: MB={:.3}m/yr  τ={:.0}Pa  v={:.4}m/yr",
        mb_ant, tau_ant, vel_ant
    );
    println!(
        "Greenland: ELA={:.0}m  V={:.2e}m³  SLE={:.1}mm  visc={:.2e}Pa·s",
        ela, vol, sle, visc
    );
    println!(
        "constants: ρ_ice={} n={} A_glen={:.2e}",
        ice_density(),
        ICE_CREEP_EXPONENT,
        GLEN_FLOW_LAW_A
    );
}