1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
mod consts;
mod structs;
mod enviro;
mod utils;

use consts::*;
use rand::prelude::*;
use serde_json::json;
use structs::system::System;

#[derive(Debug)]
pub enum AccreteOutput {
    Struct(System),
    Json(String),
}

/// ## Generate planetary system.
///
/// ### Default:
/// ```rust
/// let planets = accrete::run(None, None, None, None, None, None, false);
/// ```
///
/// Simple way to variate output is to change stellar mass. This accrete implementation is capable of generating planetary system for any stellar mass, but better (most realistic) results achieved for main sequence star class with primary star mass of 0.6 - 1.3 solar masses.
///
/// ### Configuration:
///
/// **planets_limit** - Limit number of planets.
/// *Default: None*
///
/// **stellar_mass** - Primary star mass in solar masses.
/// *Default: random f64 in a range of 0.6-1.3 (corresponds main sequence spectral classes of F-G-K)*
///
/// **dust_density_coeff** - "A" in Dole's paper, recommended range according to Dole's paper is 0.00125-0.0015, aslo noted that binary stars produced by increasing coeff of dust density in cloud (Formation of Planetary Systems by Aggregation: A Computer Simulation by Stephen H. Dole).
/// *Default: 0.0015*
///
/// **k** - The dust-to-gas ratio 50-100 (dust/gas = K), gas = hydrogen and helium, dust = other. Recommended range: 50.0-100.0
/// *Default: 50.0*
///
/// **cloud_eccentricity** - Initial dust cloud cloud_eccentricity. Recommended range: 0.15-0.25.
/// *Default: 0.20*
///
/// **b** - Crit_mass coeff is used as threshold for planet to become gas giant. Recommended range: 1.0e-5 - 1.2e-5
/// *Default: 1.2e-5*
///
/// **to_json** - Output as JSON string.
/// *Default: false*
///
pub fn run(
    planets_limit: Option<usize>,
    stellar_mass: Option<f64>,
    dust_density_coeff: Option<f64>,
    k: Option<f64>,
    cloud_eccentricity: Option<f64>,
    b: Option<f64>,
    to_json: bool,
) -> AccreteOutput {
    let mut rng = rand::thread_rng();
    let random_stellar_mass = rng.gen_range(0.6, 1.3);
    let stellar_mass = stellar_mass.unwrap_or(random_stellar_mass);

    let dust_density_coeff = dust_density_coeff.unwrap_or(DUST_DENSITY_COEFF);
    let k = k.unwrap_or(K);
    let cloud_eccentricity = cloud_eccentricity.unwrap_or(0.2);
    let b = b.unwrap_or(B);

    let mut planetary_system = System::set_initial_conditions(
        planets_limit,
        stellar_mass,
        dust_density_coeff,
        k,
        cloud_eccentricity,
        b,
    );

    planetary_system.distribute_planetary_masses();
    planetary_system.process_planets();

    if to_json {
        let s = json!({
            "primary_star": planetary_system.primary_star,
            "planets": planetary_system.planets,
        })
        .to_string();
        println!("{}", s);
        return AccreteOutput::Json(s);
    }

    for (i, p) in planetary_system.planets.iter().enumerate() {
        println!("Planet {}", i);
        println!("mass EM {}", p.mass * EARTH_MASSES_PER_SOLAR_MASS);
        println!("a {}", p.a);
        println!("is giant: {}", p.gas_giant);
        println!("Moons: {}", p.moons.len());
        println!("Rings: {}", p.rings.len());
        println!("------------------");
    }
    AccreteOutput::Struct(planetary_system)
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn run_with_default_config() {
        run(None, None, None, None, None, None, false);
    }

    #[test]
    fn run_to_json() {
        run(None, None, None, None, None, None, true);
    }

    #[test]
    fn run_with_o_spectral_class() {
        run(None, Some(60.0), None, None, None, None, false);
    }

    #[test]
    fn run_with_b_spectral_class() {
        run(None, Some(18.0), None, None, None, None, false);
    }

    #[test]
    fn run_with_a_spectral_class() {
        run(None, Some(2.1), None, None, None, None, false);
    }

    #[test]
    fn run_with_f_spectral_class() {
        run(None, Some(1.3), None, None, None, None, false);
    }

    #[test]
    fn run_with_g_spectral_class() {
        run(None, Some(1.0), None, None, None, None, false);
    }

    #[test]
    fn run_with_k_spectral_class() {
        run(None, Some(0.8), None, None, None, None, false);
    }

    #[test]
    fn run_with_m_spectral_class() {
        run(None, Some(0.3), None, None, None, None, false);
    }

    #[test]
    fn run_with_brown_dwarf() {
        run(None, Some(0.1), None, None, None, None, false);
    }

    #[test]
    fn run_with_rogue_planet() {
        run(None, Some(0.0005), None, None, None, None, false);
    }

    #[test]
    fn planets_limit() {
        run(Some(15), None, None, None, None, None, false);
    }

    #[test]
    fn massive_star() {
        run(None, Some(1.3), None, None, None, None, false);
    }

    #[test]
    fn small_star() {
        run(None, Some(0.3), None, None, None, None, false);
    }

    // "Even small increases in A result in large increases in the total mass of the systems produced; increasing A also decreases the average number of planets per system. As may be seen in Figure 17, for A = 0.003 and 0.006 the planetary system has become a binary star sys-tem, the body near 9 a.u. having grown large enough to be considered a red dwarf star. Observationally, the two stars of smallest mass now known are members of a binary system designated L726-8; each star has a mass estimated at about 0.04Ms (about 40 times the mass of Jupiter) or 13,000M e. The lower theoretical limit to the mass of a star is believed to be near 0.02Ms. It will be noticed that the binary star systems still contain numerous planetary bodies. As A is increased still more the systems become multiple-star systems and the number of planetary companions diminishes. Actually, the results at the higher values of A should be considered only suggestive of the general trend, since the total mass of the "planetary" bodies is now becoming fairly high with respect to that of the central body, so that the original simplifying assumptions, which were adequate when the total planetary mass was well below 0.01Ms, no longer apply so satisfactorily. The gravitational attractions of the several large masses for each other can no longer be considered to have negligible effects on the secular stability of the systems. This is pushing the ACRETE program somewhat beyond its original intent (to create planetary systems similar to the solar system). However, it would be readily possible to modify the program slightly to provide more rigorously for cases in which some of the planetary bodies grow to stellar mass. In any event, the general trend is clear. Simply increasing the value assigned to one parameter makes it possible to generate widely spaced binary and multiple-star systems."

    #[test]
    fn high_density_dust() {
        run(None, None, Some(0.05), None, None, None, false);
    }

    #[test]
    fn low_density_dust() {
        run(None, None, Some(0.00125), Some(25.0), None, None, false);
    }
}