use sciforge::hub::domain::common::constants::G;
pub struct Impactor {
pub diameter_m: f64,
pub density_kg_m3: f64,
pub velocity_m_s: f64,
pub impact_angle_deg: f64,
}
impl Impactor {
pub fn asteroid(diameter_m: f64, velocity_m_s: f64) -> Self {
Self {
diameter_m,
density_kg_m3: crate::STONY_ASTEROID_DENSITY,
velocity_m_s,
impact_angle_deg: 45.0,
}
}
pub fn iron_asteroid(diameter_m: f64, velocity_m_s: f64) -> Self {
Self {
diameter_m,
density_kg_m3: crate::IRON_ASTEROID_DENSITY,
velocity_m_s,
impact_angle_deg: 45.0,
}
}
pub fn mass_kg(&self) -> f64 {
let r = self.diameter_m / 2.0;
(4.0 / 3.0) * std::f64::consts::PI * r.powi(3) * self.density_kg_m3
}
pub fn kinetic_energy_j(&self) -> f64 {
0.5 * self.mass_kg() * self.velocity_m_s.powi(2)
}
pub fn kinetic_energy_mt(&self) -> f64 {
self.kinetic_energy_j() / crate::MT_TNT_TO_JOULE
}
pub fn impact_velocity(&self) -> f64 {
let vesc = (2.0 * G * crate::VENUS_MASS / crate::VENUS_RADIUS).sqrt();
(self.velocity_m_s.powi(2) + vesc.powi(2)).sqrt()
}
pub fn crater_diameter_m(&self) -> f64 {
let angle = self.impact_angle_deg.to_radians().sin().max(0.1);
1.8 * self.diameter_m.powf(0.78)
* self.impact_velocity().powf(0.44)
* angle.powf(1.0 / 3.0)
* crate::SURFACE_GRAVITY.powf(-0.22)
}
pub fn ejecta_volume_m3(&self) -> f64 {
let d = self.crater_diameter_m();
0.04 * d.powi(3)
}
}
pub fn mead_impactor() -> Impactor {
Impactor::asteroid(80_000.0, 17_000.0)
}
pub fn typical_venus_crosser() -> Impactor {
Impactor::asteroid(100.0, 20_000.0)
}