use crate::config::parameters;
pub fn mean_motion(semi_major_au: f64) -> f64 {
let period = parameters::orbital_period(semi_major_au, parameters::SOLAR_MASS);
if period < 1.0 {
return 0.0;
}
2.0 * parameters::PI / period
}
pub fn period_years(semi_major_au: f64) -> f64 {
parameters::orbital_period(semi_major_au, parameters::SOLAR_MASS) / parameters::YEAR
}
pub fn tisserand_neptune(semi_major_au: f64, eccentricity: f64, inclination_deg: f64) -> f64 {
let a_n = parameters::NEPTUNE_A;
let a_ratio = a_n / semi_major_au;
let inc = inclination_deg.to_radians();
a_ratio + 2.0 * ((semi_major_au / a_n) * (1.0 - eccentricity * eccentricity)).sqrt() * inc.cos()
}
pub fn tisserand_jupiter(semi_major_au: f64, eccentricity: f64, inclination_deg: f64) -> f64 {
let a_j: f64 = 5.2;
let a_ratio = a_j / semi_major_au;
let inc = inclination_deg.to_radians();
a_ratio + 2.0 * ((semi_major_au / a_j) * (1.0 - eccentricity * eccentricity)).sqrt() * inc.cos()
}
pub fn kepler_solve(mean_anomaly: f64, eccentricity: f64) -> f64 {
let mut ecc_anom = mean_anomaly;
for _ in 0..50 {
let de = (ecc_anom - eccentricity * ecc_anom.sin() - mean_anomaly)
/ (1.0 - eccentricity * ecc_anom.cos());
ecc_anom -= de;
if de.abs() < 1.0e-12 {
break;
}
}
ecc_anom
}
pub fn true_anomaly(ecc_anomaly: f64, eccentricity: f64) -> f64 {
2.0 * ((1.0 + eccentricity).sqrt() * (ecc_anomaly / 2.0).sin())
.atan2((1.0 - eccentricity).sqrt() * (ecc_anomaly / 2.0).cos())
}
pub fn heliocentric_distance(semi_major_au: f64, eccentricity: f64, true_anom: f64) -> f64 {
semi_major_au * (1.0 - eccentricity * eccentricity) / (1.0 + eccentricity * true_anom.cos())
}
pub fn synodic_period_neptune(semi_major_au: f64) -> f64 {
let n_body = mean_motion(semi_major_au);
let n_neptune = mean_motion(parameters::NEPTUNE_A);
let dn = (n_body - n_neptune).abs();
if dn < 1.0e-20 {
return f64::INFINITY;
}
2.0 * parameters::PI / dn
}
pub fn kozai_timescale(a_binary_m: f64, a_helio_au: f64, m_primary: f64) -> f64 {
let a_sun = a_helio_au * parameters::AU;
if a_binary_m < 1.0 || m_primary < 1.0 {
return 0.0;
}
let p_bin = 2.0 * parameters::PI * (a_binary_m.powi(3) / (parameters::G * m_primary)).sqrt();
let p_sun =
2.0 * parameters::PI * (a_sun.powi(3) / (parameters::G * parameters::SOLAR_MASS)).sqrt();
if p_bin < 1.0 {
return 0.0;
}
(p_sun * p_sun / p_bin)
* (parameters::SOLAR_MASS / m_primary)
* (1.0 - (0.3_f64).powi(2)).powf(1.5) }