use sciforge::hub::domain::astronomy::celestial::{gravitational_force, tidal_force};
use sciforge::hub::domain::common::constants::{AU, G, SOLAR_MASS};
use crate::{SOLAR_LUMINOSITY, SOLAR_RADIUS};
pub const MERCURY_MASS: f64 = 3.3011e23;
pub const VENUS_MASS: f64 = 4.8675e24;
pub const EARTH_MASS: f64 = 5.972e24;
pub const MARS_MASS: f64 = 6.4171e23;
pub const JUPITER_MASS: f64 = 1.8982e27;
pub const SATURN_MASS: f64 = 5.6834e26;
pub const URANUS_MASS: f64 = 8.6810e25;
pub const NEPTUNE_MASS: f64 = 1.02413e26;
pub const MERCURY_SEMI_MAJOR_AU: f64 = 0.387;
pub const VENUS_SEMI_MAJOR_AU: f64 = 0.723;
pub const EARTH_SEMI_MAJOR_AU: f64 = 1.000;
pub const MARS_SEMI_MAJOR_AU: f64 = 1.524;
pub const JUPITER_SEMI_MAJOR_AU: f64 = 5.203;
pub const SATURN_SEMI_MAJOR_AU: f64 = 9.537;
pub const URANUS_SEMI_MAJOR_AU: f64 = 19.191;
pub const NEPTUNE_SEMI_MAJOR_AU: f64 = 30.069;
pub struct PlanetaryTidalInteraction {
pub planet_name: &'static str,
pub planet_mass: f64,
pub orbital_distance_m: f64,
pub planet_radius_m: f64,
}
impl PlanetaryTidalInteraction {
pub fn tidal_force_on_sun(&self) -> f64 {
tidal_force(self.planet_mass, self.orbital_distance_m, SOLAR_RADIUS)
}
pub fn gravitational_pull(&self) -> f64 {
gravitational_force(SOLAR_MASS, self.planet_mass, self.orbital_distance_m)
}
pub fn tidal_bulge_height(&self) -> f64 {
let g_surface = G * SOLAR_MASS / (SOLAR_RADIUS * SOLAR_RADIUS);
let a_tidal = 2.0 * G * self.planet_mass * SOLAR_RADIUS / self.orbital_distance_m.powi(3);
a_tidal * SOLAR_RADIUS / g_surface
}
pub fn tidal_period_s(&self) -> f64 {
let mu = G * SOLAR_MASS;
2.0 * std::f64::consts::PI * (self.orbital_distance_m.powi(3) / mu).sqrt()
}
pub fn tidal_dissipation_rate(&self) -> f64 {
let q = 1e6;
let omega = 2.0 * std::f64::consts::PI / self.tidal_period_s();
let r5 = SOLAR_RADIUS.powi(5);
let d3 = self.orbital_distance_m.powi(3);
(21.0 / 2.0) * G * self.planet_mass.powi(2) * r5 * omega / (q * d3 * d3)
}
pub fn hill_sphere_radius(&self) -> f64 {
self.orbital_distance_m * (self.planet_mass / (3.0 * SOLAR_MASS)).powf(1.0 / 3.0)
}
pub fn roche_limit(&self) -> f64 {
let rho_sun = 1408.0;
let rho_planet =
self.planet_mass / ((4.0 / 3.0) * std::f64::consts::PI * self.planet_radius_m.powi(3));
self.planet_radius_m * 2.456 * (rho_sun / rho_planet).powf(1.0 / 3.0)
}
pub fn solar_flux_at_planet(&self) -> f64 {
SOLAR_LUMINOSITY
/ (4.0 * std::f64::consts::PI * self.orbital_distance_m * self.orbital_distance_m)
}
pub fn stellar_angular_momentum_loss_rate(&self) -> f64 {
let omega = 2.0 * std::f64::consts::PI / (25.05 * 86400.0);
let i = 0.07 * SOLAR_MASS * SOLAR_RADIUS * SOLAR_RADIUS;
let tau_mb = 1e10 * 3.15576e7;
i * omega / tau_mb
}
}
pub fn jupiter_interaction() -> PlanetaryTidalInteraction {
PlanetaryTidalInteraction {
planet_name: "Jupiter",
planet_mass: JUPITER_MASS,
orbital_distance_m: JUPITER_SEMI_MAJOR_AU * AU,
planet_radius_m: 6.9911e7,
}
}
pub fn earth_interaction() -> PlanetaryTidalInteraction {
PlanetaryTidalInteraction {
planet_name: "Earth",
planet_mass: EARTH_MASS,
orbital_distance_m: EARTH_SEMI_MAJOR_AU * AU,
planet_radius_m: 6.371e6,
}
}
pub fn venus_interaction() -> PlanetaryTidalInteraction {
PlanetaryTidalInteraction {
planet_name: "Venus",
planet_mass: VENUS_MASS,
orbital_distance_m: VENUS_SEMI_MAJOR_AU * AU,
planet_radius_m: 6.0518e6,
}
}
pub fn mercury_interaction() -> PlanetaryTidalInteraction {
PlanetaryTidalInteraction {
planet_name: "Mercury",
planet_mass: MERCURY_MASS,
orbital_distance_m: MERCURY_SEMI_MAJOR_AU * AU,
planet_radius_m: 2.4397e6,
}
}
pub fn saturn_interaction() -> PlanetaryTidalInteraction {
PlanetaryTidalInteraction {
planet_name: "Saturn",
planet_mass: SATURN_MASS,
orbital_distance_m: SATURN_SEMI_MAJOR_AU * AU,
planet_radius_m: 5.8232e7,
}
}
pub fn total_planetary_tidal_force() -> f64 {
let planets: [PlanetaryTidalInteraction; 5] = [
jupiter_interaction(),
earth_interaction(),
venus_interaction(),
mercury_interaction(),
saturn_interaction(),
];
planets.iter().map(|p| p.tidal_force_on_sun()).sum()
}
pub fn solar_barycenter_offset() -> f64 {
let jup = jupiter_interaction();
jup.planet_mass * jup.orbital_distance_m / SOLAR_MASS
}
pub fn radiation_pressure_at_distance(distance_m: f64) -> f64 {
SOLAR_LUMINOSITY
/ (4.0 * std::f64::consts::PI * distance_m * distance_m * crate::SPEED_OF_LIGHT)
}
pub fn poynting_robertson_drag_timescale(
particle_radius_m: f64,
density: f64,
distance_au: f64,
) -> f64 {
let c = crate::SPEED_OF_LIGHT;
let r = distance_au * AU;
let m_p = (4.0 / 3.0) * std::f64::consts::PI * particle_radius_m.powi(3) * density;
let sigma = std::f64::consts::PI * particle_radius_m * particle_radius_m;
let l = SOLAR_LUMINOSITY;
m_p * c * c * r * r / (l * sigma)
}