use sciforge::hub::domain::astronomy::orbits::escape_velocity;
use sciforge::hub::domain::common::constants::{EARTH_MASS, EARTH_RADIUS, G};
pub struct Impactor {
pub masskg: f64,
pub velocityms: f64,
pub densitykgm3: f64,
pub angledeg: f64,
}
impl Impactor {
pub fn asteroid(diameterm: f64, velocitykms: f64) -> Self {
let density = crate::STONYASTEROIDDENSITY;
let radius = diameterm / 2.0;
let volume = (4.0 / 3.0) * std::f64::consts::PI * radius.powi(3);
Self {
masskg: density * volume,
velocityms: velocitykms * 1000.0,
densitykgm3: density,
angledeg: 45.0,
}
}
pub fn kineticenergyj(&self) -> f64 {
0.5 * self.masskg * self.velocityms.powi(2)
}
pub fn kineticenergymt(&self) -> f64 {
self.kineticenergyj() / crate::MTTNTTOJOULE
}
pub fn impactvelocity(&self) -> f64 {
let vesc = escape_velocity(G * EARTH_MASS, EARTH_RADIUS);
(self.velocityms.powi(2) + vesc.powi(2)).sqrt()
}
pub fn craterdiameterm(&self, targetdensity: f64) -> f64 {
let g = G * EARTH_MASS / (EARTH_RADIUS * EARTH_RADIUS);
let anglerad = self.angledeg.to_radians();
let dprojectile = (6.0 * self.masskg / (std::f64::consts::PI * self.densitykgm3)).cbrt();
1.161
* (self.densitykgm3 / targetdensity).powf(1.0 / 3.0)
* dprojectile.powf(0.78)
* self.velocityms.powf(0.44)
* g.powf(-0.22)
* anglerad.sin().powf(1.0 / 3.0)
}
pub fn fireballradiusm(&self) -> f64 {
let energykt = self.kineticenergyj() / crate::KTTNTTOJOULE;
55.0 * energykt.powf(0.4)
}
pub fn ejectavolumem3(&self, targetdensity: f64) -> f64 {
let craterd = self.craterdiameterm(targetdensity);
let craterdepth = craterd / 5.0;
std::f64::consts::PI / 6.0 * craterd * craterd * craterdepth
}
}
pub fn chicxulubequivalent() -> Impactor {
Impactor::asteroid(10000.0, 20.0)
}
pub fn tunguskaequivalent() -> Impactor {
Impactor::asteroid(60.0, 15.0)
}