planetsfactory 0.0.1

Planet factory — classify, build and catalogue planets for any star system: Solar System, TRAPPIST-1, Kepler-90, Proxima Centauri, or fully custom worlds.
Documentation
use std::process;

use planetsfactory::config::parameters::*;
use planetsfactory::engine::generator::{SystemGeneratorConfig, generate_system};
use planetsfactory::engine::orbits::elements_to_state;
use planetsfactory::observables::radial_velocity::rv_semi_amplitude;
use planetsfactory::observables::transits::transit_depth;
use planetsfactory::physics::atmospheres::Atmosphere;
use planetsfactory::physics::gravitation::PlanetaryGravity;
use planetsfactory::physics::interiors::PlanetaryInterior;
use planetsfactory::presets::solar_system;
use planetsfactory::types::gas_giant::GasGiant;
use planetsfactory::types::ice_giant::IceGiant;
use planetsfactory::types::terrestrial::TerrestrialPlanet;

struct FactoryValidation {
    earth_mass: f64,
    earth_gravity: f64,
    earth_escape_v: f64,
    earth_density: f64,
    jupiter_mass_j: f64,
    jupiter_gravity: f64,
    saturn_ring_roche: f64,
    uranus_ice_frac: f64,
    neptune_wind: f64,
    hill_radius_earth: f64,
    atm_scale_height: f64,
    interior_moi: f64,
    transit_depth_jup: f64,
    rv_earth: f64,
    solar_system_count: usize,
    generated_count: usize,
    kepler90_count: usize,
    trappist1_count: usize,
    proxima_count: usize,
    cartesian_r: f64,
}

impl FactoryValidation {
    fn passed(&self) -> bool {
        let types_ok = (self.earth_mass - 1.0).abs() < 0.01
            && self.earth_gravity > 9.0
            && self.earth_gravity < 10.5
            && self.earth_escape_v > 1e4
            && self.earth_density > 5000.0
            && self.earth_density < 6000.0
            && self.jupiter_mass_j > 0.99
            && self.jupiter_mass_j < 1.01
            && self.jupiter_gravity > 20.0
            && self.saturn_ring_roche > 0.0
            && self.uranus_ice_frac > 0.5
            && self.neptune_wind > 200.0;

        let physics_ok = self.hill_radius_earth > 0.0
            && self.atm_scale_height > 7000.0
            && self.atm_scale_height < 10000.0
            && self.interior_moi > 0.3
            && self.interior_moi < 0.4;

        let obs_ok =
            self.transit_depth_jup > 0.0 && self.transit_depth_jup < 0.02 && self.rv_earth > 0.0;

        let presets_ok = self.solar_system_count == 8
            && self.generated_count >= 4
            && self.kepler90_count == 8
            && self.trappist1_count == 7
            && self.proxima_count == 2;

        let orbit_ok = self.cartesian_r > 1.4e11 && self.cartesian_r < 1.6e11;

        types_ok && physics_ok && obs_ok && presets_ok && orbit_ok
    }
}

fn main() {
    let earth = TerrestrialPlanet::earth();
    let jupiter = GasGiant::jupiter();
    let saturn = GasGiant::saturn();
    let uranus = IceGiant::uranus();
    let neptune = IceGiant::neptune();

    let earth_grav = PlanetaryGravity::new(earth.mass, earth.radius);
    let atm = Atmosphere::earth();
    let interior = PlanetaryInterior::earth();

    let (pos, _vel) = elements_to_state(&earth.elements, SOLAR_MASS + earth.mass);
    let r = (pos[0] * pos[0] + pos[1] * pos[1] + pos[2] * pos[2]).sqrt();

    let depth = transit_depth(jupiter.radius, SOLAR_RADIUS);
    let rv = rv_semi_amplitude(
        earth.mass,
        SOLAR_MASS,
        earth.elements.a,
        earth.elements.e,
        std::f64::consts::FRAC_PI_2,
    );

    let solar = solar_system::all();
    let config = SystemGeneratorConfig::solar_like(6);
    let generated = generate_system(&config);

    let kepler90 = planetsfactory::presets::kepler90::all();
    let trappist1 = planetsfactory::presets::trappist1::all();
    let proxima = planetsfactory::presets::proxima_centauri::all();

    let v = FactoryValidation {
        earth_mass: earth.mass_earth(),
        earth_gravity: earth.surface_gravity(),
        earth_escape_v: earth.escape_velocity(),
        earth_density: earth.mean_density(),
        jupiter_mass_j: jupiter.mass_jupiter(),
        jupiter_gravity: jupiter.surface_gravity(),
        saturn_ring_roche: saturn.ring_roche_limit(900.0),
        uranus_ice_frac: uranus.ice_mass_fraction,
        neptune_wind: neptune.wind_speed_estimate(),
        hill_radius_earth: earth_grav.sphere_of_influence(AU, SOLAR_MASS),
        atm_scale_height: atm.scale_height,
        interior_moi: interior.moment_of_inertia_factor(),
        transit_depth_jup: depth,
        rv_earth: rv,
        solar_system_count: solar.len(),
        generated_count: generated.len(),
        kepler90_count: kepler90.len(),
        trappist1_count: trappist1.len(),
        proxima_count: proxima.len(),
        cartesian_r: r,
    };

    if v.passed() {
        process::exit(0);
    } else {
        process::exit(1);
    }
}