venuss 0.0.3

Venus celestial simulation crate for the MilkyWay SolarSystem workspace
Documentation
pub struct CloudLayer {
    pub name: &'static str,
    pub base_altitude_m: f64,
    pub top_altitude_m: f64,
    pub optical_depth: f64,
    pub composition: &'static str,
    pub particle_radius_um: f64,
    pub single_scatter_albedo: f64,
}

pub struct CloudSystemEndpoint {
    pub layers: Vec<CloudLayer>,
    pub total_optical_depth: f64,
}

impl CloudSystemEndpoint {
    pub fn venus_default() -> Self {
        let layers = vec![
            CloudLayer {
                name: "lower_cloud",
                base_altitude_m: 47_500.0,
                top_altitude_m: 50_000.0,
                optical_depth: 6.0,
                composition: "H2SO4 (75-85 wt%)",
                particle_radius_um: 3.5,
                single_scatter_albedo: 0.999,
            },
            CloudLayer {
                name: "middle_cloud",
                base_altitude_m: 50_000.0,
                top_altitude_m: 57_000.0,
                optical_depth: 10.0,
                composition: "H2SO4 + S8 particles",
                particle_radius_um: 2.5,
                single_scatter_albedo: 0.998,
            },
            CloudLayer {
                name: "upper_cloud",
                base_altitude_m: 57_000.0,
                top_altitude_m: 70_000.0,
                optical_depth: 9.0,
                composition: "H2SO4 fine mist",
                particle_radius_um: 1.0,
                single_scatter_albedo: 0.997,
            },
        ];
        let total = layers.iter().map(|l| l.optical_depth).sum();
        Self {
            layers,
            total_optical_depth: total,
        }
    }

    pub fn cloud_top_altitude_m(&self) -> f64 {
        self.layers
            .iter()
            .map(|l| l.top_altitude_m)
            .fold(0.0_f64, f64::max)
    }

    pub fn cloud_base_altitude_m(&self) -> f64 {
        self.layers
            .iter()
            .map(|l| l.base_altitude_m)
            .fold(f64::MAX, f64::min)
    }

    pub fn transmission(&self) -> f64 {
        (-self.total_optical_depth).exp()
    }

    pub fn layer_at_altitude(&self, altitude_m: f64) -> Option<&CloudLayer> {
        self.layers
            .iter()
            .find(|l| altitude_m >= l.base_altitude_m && altitude_m <= l.top_altitude_m)
    }
}

pub fn cloud_top_altitude_m() -> f64 {
    65_000.0
}

pub fn cloud_base_altitude_m() -> f64 {
    45_000.0
}