use crate::config::parameters::*;
use crate::engine::orbits::OrbitalElements;
pub type Vec3 = [f64; 3];
#[derive(Debug, Clone)]
pub struct Exomoon {
pub name: String,
pub parent: String,
pub mass: f64,
pub radius: f64,
pub j2: f64,
pub obliquity: f64,
pub elements: OrbitalElements,
pub albedo: f64,
pub parent_mass: f64,
pub star_mass: f64,
pub star_planet_distance: f64,
}
impl Exomoon {
pub fn new(
name: &str,
parent: &str,
mass: f64,
radius: f64,
j2: f64,
obliquity: f64,
elements: OrbitalElements,
) -> Self {
Self {
name: name.to_string(),
parent: parent.to_string(),
mass,
radius,
j2,
obliquity,
elements,
albedo: 0.30,
parent_mass: 1.898e27,
star_mass: M_SUN,
star_planet_distance: AU,
}
}
pub fn with_system(
mut self,
albedo: f64,
parent_mass: f64,
star_mass: f64,
star_planet_distance: f64,
) -> Self {
self.albedo = albedo;
self.parent_mass = parent_mass;
self.star_mass = star_mass;
self.star_planet_distance = star_planet_distance;
self
}
pub fn surface_gravity(&self) -> f64 {
surface_gravity(self.mass, self.radius)
}
pub fn escape_velocity(&self) -> f64 {
escape_velocity(self.mass, self.radius)
}
pub fn mean_density(&self) -> f64 {
mean_density(self.mass, self.radius)
}
pub fn period(&self) -> f64 {
self.elements.period(G * (self.parent_mass + self.mass))
}
pub fn to_cartesian(&self) -> (Vec3, Vec3) {
crate::engine::orbits::elements_to_state(&self.elements, self.parent_mass + self.mass)
}
pub fn hill_radius(&self) -> f64 {
self.star_planet_distance * (self.parent_mass / (3.0 * self.star_mass)).cbrt()
}
pub fn hill_stability_ratio(&self) -> f64 {
self.elements.a / self.hill_radius()
}
pub fn is_hill_stable(&self) -> bool {
self.hill_stability_ratio() < 0.49
}
pub fn transit_depth(&self) -> f64 {
let r_star = (self.star_mass / M_SUN).powf(0.8) * R_SUN;
(self.radius / r_star).powi(2)
}
pub fn transit_timing_variation(&self) -> f64 {
let p_planet =
(4.0 * std::f64::consts::PI * std::f64::consts::PI * self.star_planet_distance.powi(3)
/ (G * (self.star_mass + self.parent_mass)))
.sqrt();
let ratio = self.mass / self.parent_mass;
p_planet * ratio * (self.elements.a / self.star_planet_distance)
}
pub fn equilibrium_temperature(&self) -> f64 {
let l_star = L_SUN * (self.star_mass / M_SUN).powf(3.5);
let factor = l_star * (1.0 - self.albedo)
/ (16.0
* std::f64::consts::PI
* STEFAN_BOLTZMANN
* self.star_planet_distance
* self.star_planet_distance);
factor.powf(0.25)
}
pub fn tidal_locking_timescale(&self) -> f64 {
let q = 100.0;
let k2 = 0.03;
let omega0 = 2.0 * std::f64::consts::PI / 36000.0;
let prefactor = omega0 * self.elements.a.powi(6) * q;
let denom = 3.0 * k2 * G * self.parent_mass * self.parent_mass * self.radius.powi(3);
prefactor / denom
}
}