marss 0.0.3

Mars celestial simulation crate for the MilkyWay SolarSystem workspace
Documentation
use sciforge::hub::domain::geology::petrology::{
    differentiation_index, liquidus_temperature, mg_number, solidus_depression,
};

pub struct MarsVolcanism {
    pub currently_active: bool,
    pub tharsis_province_area_km2: f64,
    pub elysium_province_area_km2: f64,
}

impl Default for MarsVolcanism {
    fn default() -> Self {
        Self::new()
    }
}

impl MarsVolcanism {
    pub fn new() -> Self {
        Self {
            currently_active: false,
            tharsis_province_area_km2: 30_000_000.0,
            elysium_province_area_km2: 5_000_000.0,
        }
    }

    pub fn total_volcanic_coverage(&self) -> f64 {
        let total = self.tharsis_province_area_km2 + self.elysium_province_area_km2;
        total * 1e6 / crate::MARS_SURFACE_AREA
    }

    pub fn last_eruption_estimate_myr(&self) -> f64 {
        2.0
    }

    pub fn major_volcanoes() -> Vec<MarsVolcano> {
        vec![
            MarsVolcano {
                name: "Olympus Mons",
                height_m: 21_900.0,
                diameter_km: 624.0,
                caldera_diameter_km: 80.0,
            },
            MarsVolcano {
                name: "Ascraeus Mons",
                height_m: 18_100.0,
                diameter_km: 460.0,
                caldera_diameter_km: 40.0,
            },
            MarsVolcano {
                name: "Pavonis Mons",
                height_m: 14_000.0,
                diameter_km: 375.0,
                caldera_diameter_km: 47.0,
            },
            MarsVolcano {
                name: "Arsia Mons",
                height_m: 17_800.0,
                diameter_km: 475.0,
                caldera_diameter_km: 110.0,
            },
            MarsVolcano {
                name: "Elysium Mons",
                height_m: 14_100.0,
                diameter_km: 240.0,
                caldera_diameter_km: 14.0,
            },
            MarsVolcano {
                name: "Alba Mons",
                height_m: 6_800.0,
                diameter_km: 1015.0,
                caldera_diameter_km: 100.0,
            },
        ]
    }
}

pub struct MarsVolcano {
    pub name: &'static str,
    pub height_m: f64,
    pub diameter_km: f64,
    pub caldera_diameter_km: f64,
}

impl MarsVolcano {
    pub fn slope_angle_deg(&self) -> f64 {
        let h = self.height_m;
        let r = self.diameter_km * 500.0;
        (h / r).atan().to_degrees()
    }

    pub fn volume_km3(&self) -> f64 {
        let r = self.diameter_km / 2.0;
        let h = self.height_m / 1000.0;
        std::f64::consts::PI / 3.0 * r * r * h
    }
}

pub struct MarsMagma {
    pub sio2_wt_percent: f64,
    pub mgo_wt_percent: f64,
    pub feo_wt_percent: f64,
    pub h2o_wt_percent: f64,
    pub temperature_c: f64,
}

impl MarsMagma {
    pub fn tholeiitic_basalt() -> Self {
        Self {
            sio2_wt_percent: 46.0,
            mgo_wt_percent: 9.0,
            feo_wt_percent: 18.0,
            h2o_wt_percent: 0.5,
            temperature_c: 1250.0,
        }
    }

    pub fn alkaline_basalt() -> Self {
        Self {
            sio2_wt_percent: 44.0,
            mgo_wt_percent: 12.0,
            feo_wt_percent: 15.0,
            h2o_wt_percent: 1.0,
            temperature_c: 1300.0,
        }
    }

    pub fn mg_number(&self) -> f64 {
        mg_number(self.mgo_wt_percent, self.feo_wt_percent)
    }

    pub fn liquidus_temp_c(&self) -> f64 {
        liquidus_temperature(self.sio2_wt_percent, self.h2o_wt_percent, 1050.0)
    }

    pub fn solidus_depression_c(&self) -> f64 {
        solidus_depression(self.h2o_wt_percent, 1050.0, 1.0)
    }

    pub fn differentiation_idx(&self) -> f64 {
        differentiation_index(
            self.sio2_wt_percent,
            self.mgo_wt_percent,
            self.feo_wt_percent,
            0.0,
        )
    }
}