use sciforge::hub::prelude::constants::elements::atomic_mass;
pub struct ExosphereSpecies {
pub name: &'static str,
pub symbol: &'static str,
pub molar_mass_kg_mol: f64,
pub column_density_m2: f64,
pub scale_height_m: f64,
}
pub struct CryovolcanicEndpoint {
pub geyser_height_m: f64,
pub n2_mass_rate_kg_s: f64,
pub surface_pressure_pa: f64,
}
pub struct ExosphereEndpoint {
pub body_radius_m: f64,
pub species: Vec<ExosphereSpecies>,
}
fn n2_molar() -> f64 {
2.0 * atomic_mass(7) * 1e-3
}
fn ch4_molar() -> f64 {
(atomic_mass(6) + 4.0 * atomic_mass(1)) * 1e-3
}
fn co_molar() -> f64 {
(atomic_mass(6) + atomic_mass(8)) * 1e-3
}
fn co2_molar() -> f64 {
(atomic_mass(6) + 2.0 * atomic_mass(8)) * 1e-3
}
impl ExosphereEndpoint {
pub fn triton() -> Self {
Self {
body_radius_m: crate::TRITON_RADIUS_M,
species: vec![
ExosphereSpecies {
name: "Dinitrogen",
symbol: "N2",
molar_mass_kg_mol: n2_molar(),
column_density_m2: 1e20,
scale_height_m: 50_000.0,
},
ExosphereSpecies {
name: "Methane",
symbol: "CH4",
molar_mass_kg_mol: ch4_molar(),
column_density_m2: 1e16,
scale_height_m: 20_000.0,
},
ExosphereSpecies {
name: "Carbon monoxide",
symbol: "CO",
molar_mass_kg_mol: co_molar(),
column_density_m2: 1e15,
scale_height_m: 30_000.0,
},
ExosphereSpecies {
name: "Carbon dioxide",
symbol: "CO2",
molar_mass_kg_mol: co2_molar(),
column_density_m2: 1e14,
scale_height_m: 15_000.0,
},
],
}
}
pub fn density_at_altitude(&self, species_symbol: &str, altitude_m: f64) -> f64 {
self.species
.iter()
.find(|s| s.symbol == species_symbol)
.map(|s| {
let n_surface = s.column_density_m2 / s.scale_height_m;
n_surface * (-altitude_m / s.scale_height_m).exp()
})
.unwrap_or(0.0)
}
pub fn total_column_density(&self) -> f64 {
self.species.iter().map(|s| s.column_density_m2).sum()
}
}
impl CryovolcanicEndpoint {
pub fn triton_geyser() -> Self {
Self {
geyser_height_m: 8_000.0,
n2_mass_rate_kg_s: 10.0,
surface_pressure_pa: 1.4,
}
}
pub fn plume_density_at_height(&self, height_m: f64) -> f64 {
if height_m > self.geyser_height_m {
return 0.0;
}
let frac = height_m / self.geyser_height_m;
self.n2_mass_rate_kg_s * (1.0 - frac).powi(2)
}
}