dwarfplanetsfactory 0.0.1

Dwarf planet factory — classify, build and catalogue dwarf planets of any type: Kuiper belt, scattered disk, plutino, cold classical, detached, binary, Ceres-type, and sednoid.
Documentation
use crate::config::parameters;

/// Gravitational binding energy |U| = 3 G M² / (5 R)
pub fn binding_energy(mass: f64, radius: f64) -> f64 {
    if radius < 1.0 {
        return 0.0;
    }
    3.0 * parameters::G * mass * mass / (5.0 * radius)
}

/// Tidal acceleration from the Sun at distance r (AU)
pub fn solar_tidal_acceleration(body_radius: f64, r_au: f64) -> f64 {
    let r = r_au * parameters::AU;
    if r < 1.0 {
        return 0.0;
    }
    2.0 * parameters::G * parameters::SOLAR_MASS * body_radius / (r * r * r)
}

/// Tidal force from a close encounter with Neptune
pub fn neptune_tidal_acceleration(body_radius: f64, distance_au: f64) -> f64 {
    let r = distance_au * parameters::AU;
    if r < 1.0 {
        return 0.0;
    }
    2.0 * parameters::G * parameters::NEPTUNE_MASS * body_radius / (r * r * r)
}

/// Hill sphere radius (m) around the Sun
pub fn hill_radius(semi_major_au: f64, body_mass: f64) -> f64 {
    parameters::hill_sphere(
        semi_major_au * parameters::AU,
        body_mass,
        parameters::SOLAR_MASS,
    )
}

/// Roche limit (m) for a fluid body with density rho near a central
/// mass with radius R_central and density rho_central
pub fn roche_limit(central_radius: f64, central_density: f64, body_density: f64) -> f64 {
    if body_density < 1.0 {
        return 0.0;
    }
    2.44 * central_radius * (central_density / body_density).powf(1.0 / 3.0)
}

/// Specific orbital energy (J/kg) for a circular orbit at distance r (AU)
pub fn specific_orbital_energy(semi_major_au: f64) -> f64 {
    let a = semi_major_au * parameters::AU;
    if a < 1.0 {
        return 0.0;
    }
    -parameters::G * parameters::SOLAR_MASS / (2.0 * a)
}

/// Orbital velocity at distance r (AU) for an elliptical orbit with
/// semi-major axis a (AU)
pub fn orbital_velocity(r_au: f64, a_au: f64) -> f64 {
    let r = r_au * parameters::AU;
    let a = a_au * parameters::AU;
    if r < 1.0 || a < 1.0 {
        return 0.0;
    }
    (parameters::G * parameters::SOLAR_MASS * (2.0 / r - 1.0 / a)).sqrt()
}

/// Angular momentum per unit mass (m²/s) for an orbit
pub fn specific_angular_momentum(semi_major_au: f64, eccentricity: f64) -> f64 {
    let a = semi_major_au * parameters::AU;
    (parameters::G * parameters::SOLAR_MASS * a * (1.0 - eccentricity * eccentricity)).sqrt()
}