suns 0.0.1

Sun celestial simulation crate for the MilkyWay SolarSystem workspace
Documentation
use suns::interactions::tidal_forces::{
    PlanetaryTidalInteraction, earth_interaction, jupiter_interaction, mercury_interaction,
    poynting_robertson_drag_timescale, radiation_pressure_at_distance, saturn_interaction,
    solar_barycenter_offset, total_planetary_tidal_force, venus_interaction,
};

#[test]
fn jupiter_strongest_tidal_force() {
    let jup = jupiter_interaction().tidal_force_on_sun();
    let earth = earth_interaction().tidal_force_on_sun();
    let venus = venus_interaction().tidal_force_on_sun();
    assert!(jup > earth, "Jupiter tidal > Earth");
    assert!(jup > venus, "Jupiter tidal > Venus");
}

#[test]
fn gravitational_pull_positive() {
    for p in [
        jupiter_interaction(),
        earth_interaction(),
        venus_interaction(),
        mercury_interaction(),
    ] {
        assert!(
            p.gravitational_pull() > 0.0,
            "{} grav pull <= 0",
            p.planet_name
        );
    }
}

#[test]
fn tidal_force_positive() {
    for p in [
        jupiter_interaction(),
        earth_interaction(),
        saturn_interaction(),
    ] {
        assert!(p.tidal_force_on_sun() > 0.0, "{} tidal <= 0", p.planet_name);
    }
}

#[test]
fn tidal_bulge_height_positive() {
    assert!(jupiter_interaction().tidal_bulge_height() > 0.0);
}

#[test]
fn tidal_period_positive() {
    assert!(earth_interaction().tidal_period_s() > 0.0);
}

#[test]
fn hill_sphere_jupiter_large() {
    let r = jupiter_interaction().hill_sphere_radius();
    assert!(r > 1e10, "Jupiter Hill sphere={r}m");
}

#[test]
fn roche_limit_inside_orbit() {
    let p = jupiter_interaction();
    assert!(p.roche_limit() < p.orbital_distance_m);
}

#[test]
fn solar_flux_decreases_with_distance() {
    let f_earth = earth_interaction().solar_flux_at_planet();
    let f_jup = jupiter_interaction().solar_flux_at_planet();
    assert!(f_earth > f_jup, "Earth flux > Jupiter flux");
}

#[test]
fn solar_flux_at_earth_about_1361() {
    let f = earth_interaction().solar_flux_at_planet();
    assert!((f - 1361.0).abs() < 200.0, "solar constant={f}");
}

#[test]
fn total_planetary_tidal_force_positive() {
    assert!(total_planetary_tidal_force() > 0.0);
}

#[test]
fn total_tidal_greater_than_jupiter_alone() {
    let total = total_planetary_tidal_force();
    let jup = jupiter_interaction().tidal_force_on_sun();
    assert!(total >= jup);
}

#[test]
fn barycenter_offset_positive() {
    let offset = solar_barycenter_offset();
    assert!(offset > 0.0);
}

#[test]
fn barycenter_offset_within_sun() {
    let offset = solar_barycenter_offset();
    // The barycenter may be outside the Sun due to Jupiter, but should be within ~2 solar radii
    assert!(offset < 3.0 * suns::SOLAR_RADIUS, "offset={offset}m");
}

#[test]
fn radiation_pressure_decreases_with_distance() {
    let p1 = radiation_pressure_at_distance(1.496e11);
    let p2 = radiation_pressure_at_distance(2.0 * 1.496e11);
    assert!(p1 > p2);
}

#[test]
fn radiation_pressure_positive() {
    assert!(radiation_pressure_at_distance(1.496e11) > 0.0);
}

#[test]
fn poynting_robertson_timescale_positive() {
    let t = poynting_robertson_drag_timescale(1e-3, 3000.0, 1.0);
    assert!(t > 0.0);
}

#[test]
fn poynting_robertson_longer_for_large_particles() {
    let t_small = poynting_robertson_drag_timescale(1e-6, 3000.0, 1.0);
    let t_large = poynting_robertson_drag_timescale(1e-3, 3000.0, 1.0);
    assert!(t_large > t_small);
}

#[test]
fn mercury_closer_than_earth() {
    assert!(mercury_interaction().orbital_distance_m < earth_interaction().orbital_distance_m);
}

#[test]
fn mercury_higher_solar_flux() {
    let f_merc = mercury_interaction().solar_flux_at_planet();
    let f_earth = earth_interaction().solar_flux_at_planet();
    assert!(f_merc > f_earth);
}