use sciforge::hub::prelude::constants::elements::atomic_mass;
pub struct ExosphereSpecies {
pub name: &'static str,
pub symbol: &'static str,
pub atomic_number: u32,
pub molar_mass_kg_mol: f64,
pub column_density_cm2: f64,
pub scale_height_km: f64,
pub source_mechanism: &'static str,
}
pub struct ExosphereEndpoint {
pub planet_radius_m: f64,
pub surface_pressure_pa: f64,
pub species: Vec<ExosphereSpecies>,
pub solar_wind_sputtering_rate: f64,
}
impl ExosphereEndpoint {
pub fn mercury() -> Self {
Self {
planet_radius_m: 2_439_700.0,
surface_pressure_pa: crate::EXOSPHERE_SURFACE_PRESSURE_PA,
species: vec![
ExosphereSpecies {
name: "Sodium",
symbol: "Na",
atomic_number: 11,
molar_mass_kg_mol: atomic_mass(11) * 1e-3,
column_density_cm2: crate::NA_COLUMN_DENSITY,
scale_height_km: crate::NA_SCALE_HEIGHT_KM,
source_mechanism: "photon-stimulated desorption + sputtering",
},
ExosphereSpecies {
name: "Potassium",
symbol: "K",
atomic_number: 19,
molar_mass_kg_mol: atomic_mass(19) * 1e-3,
column_density_cm2: crate::K_COLUMN_DENSITY,
scale_height_km: crate::K_SCALE_HEIGHT_KM,
source_mechanism: "photon-stimulated desorption",
},
ExosphereSpecies {
name: "Helium",
symbol: "He",
atomic_number: 2,
molar_mass_kg_mol: atomic_mass(2) * 1e-3,
column_density_cm2: crate::HE_COLUMN_DENSITY,
scale_height_km: crate::HE_SCALE_HEIGHT_KM,
source_mechanism: "solar wind capture + radiogenic",
},
ExosphereSpecies {
name: "Calcium",
symbol: "Ca",
atomic_number: 20,
molar_mass_kg_mol: atomic_mass(20) * 1e-3,
column_density_cm2: crate::CA_COLUMN_DENSITY,
scale_height_km: 50.0,
source_mechanism: "meteoroid impact vaporization",
},
ExosphereSpecies {
name: "Magnesium",
symbol: "Mg",
atomic_number: 12,
molar_mass_kg_mol: atomic_mass(12) * 1e-3,
column_density_cm2: crate::MG_COLUMN_DENSITY,
scale_height_km: 65.0,
source_mechanism: "meteoroid impact + sputtering",
},
ExosphereSpecies {
name: "Oxygen",
symbol: "O",
atomic_number: 8,
molar_mass_kg_mol: atomic_mass(8) * 1e-3,
column_density_cm2: crate::O_COLUMN_DENSITY,
scale_height_km: 150.0,
source_mechanism: "photodissociation of surface oxides",
},
ExosphereSpecies {
name: "Hydrogen",
symbol: "H",
atomic_number: 1,
molar_mass_kg_mol: atomic_mass(1) * 1e-3,
column_density_cm2: crate::H_COLUMN_DENSITY,
scale_height_km: 400.0,
source_mechanism: "solar wind proton neutralization",
},
],
solar_wind_sputtering_rate: 1.0e24,
}
}
pub fn density_at_altitude(&self, species_symbol: &str, altitude_km: f64) -> f64 {
if let Some(s) = self.species.iter().find(|sp| sp.symbol == species_symbol) {
s.column_density_cm2 / (s.scale_height_km * 1e5)
* (-altitude_km / s.scale_height_km).exp()
} else {
0.0
}
}
pub fn sodium_glow_intensity(&self, sun_distance_au: f64) -> f64 {
let base = 1.0e6;
base / (sun_distance_au * sun_distance_au)
}
pub fn total_column_density(&self) -> f64 {
self.species.iter().map(|s| s.column_density_cm2).sum()
}
}
pub fn scattering_coefficients() -> (f64, f64) {
(0.0, 0.0)
}
pub fn rayleigh_coefficients() -> [f64; 3] {
[0.0, 0.0, 0.0]
}
pub fn mie_coefficient() -> f64 {
0.0
}
pub fn optical_depth(altitude_m: f64, zenith_cos: f64) -> f64 {
if altitude_m.is_finite() && zenith_cos.is_finite() {
0.0
} else {
f64::NAN
}
}
pub fn sky_color(sun_elevation_rad: f64) -> [f32; 3] {
if sun_elevation_rad.is_finite() {
[0.0, 0.0, 0.0]
} else {
[f32::NAN; 3]
}
}
pub fn sodium_glow_intensity(sun_distance_au: f64) -> f64 {
let base = 1.0e6;
base / (sun_distance_au * sun_distance_au)
}