suns 0.0.1

Sun celestial simulation crate for the MilkyWay SolarSystem workspace
Documentation
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)
}