satellitesfactory 0.0.1

Satellite factory — classify, build and catalogue natural satellites for any planetary system: Solar System moons (Moon, Galileans, Titan, Triton…) or custom configurations.
Documentation
use crate::config::parameters::*;
use crate::engine::orbits::OrbitalElements;

pub type Vec3 = [f64; 3];

#[derive(Debug, Clone)]
pub struct CapturedSatellite {
    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 retrograde: bool,
    pub capture_velocity_excess: f64,
    pub composition: CapturedComposition,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CapturedComposition {
    Carbonaceous,
    Silicate,
    IceRich,
}

impl CapturedSatellite {
    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.06,
            retrograde: false,
            capture_velocity_excess: 200.0,
            composition: CapturedComposition::Carbonaceous,
        }
    }

    pub fn with_capture(
        mut self,
        albedo: f64,
        retrograde: bool,
        capture_velocity_excess: f64,
        composition: CapturedComposition,
    ) -> Self {
        self.albedo = albedo;
        self.retrograde = retrograde;
        self.capture_velocity_excess = capture_velocity_excess;
        self.composition = composition;
        self
    }

    pub fn mass_moon(&self) -> f64 {
        self.mass / MOON_MASS
    }

    pub fn radius_moon(&self) -> f64 {
        self.radius / MOON_RADIUS
    }

    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, parent_mass: f64) -> f64 {
        self.elements.period(G * (parent_mass + self.mass))
    }

    pub fn to_cartesian(&self, parent_mass: f64) -> (Vec3, Vec3) {
        crate::engine::orbits::elements_to_state(&self.elements, parent_mass + self.mass)
    }

    pub fn is_retrograde(&self) -> bool {
        self.retrograde
    }

    pub fn capture_energy(&self) -> f64 {
        0.5 * self.mass * self.capture_velocity_excess * self.capture_velocity_excess
    }

    pub fn tidal_circularization_time(
        &self,
        parent_mass: f64,
        parent_radius: f64,
        q_tidal: f64,
    ) -> f64 {
        let a = self.elements.a;
        let e = self.elements.e;
        if e < 1e-12 {
            return f64::INFINITY;
        }
        let n = (G * parent_mass / a.powi(3)).sqrt();
        (2.0 * q_tidal * self.mass * a.powi(5) * n)
            / (63.0 * G * parent_mass * parent_mass * parent_radius.powi(5))
    }
}