use crate::config::parameters::*;
use std::f64::consts::PI;
pub struct PlanetEvolution {
pub mass: f64,
pub radius: f64,
pub age: f64,
pub semi_major: f64,
pub stellar_luminosity: f64,
}
impl PlanetEvolution {
pub fn new(mass: f64, radius: f64, semi_major: f64, stellar_luminosity: f64) -> Self {
Self {
mass,
radius,
age: 0.0,
semi_major,
stellar_luminosity,
}
}
pub fn cooling_luminosity(&self) -> f64 {
let t_eff = 150.0
* (JUPITER_MASS / self.mass).powf(0.3)
* (1e9 * YEAR / (self.age + 1e6 * YEAR)).powf(0.3);
let area = 4.0 * PI * self.radius * self.radius;
SIGMA_SB * t_eff.powi(4) * area
}
pub fn radius_at_age(&self, age: f64) -> f64 {
if self.mass > 50.0 * EARTH_MASS {
self.radius * (1.0 + 0.1 * (1e9 * YEAR / (age + 1e6 * YEAR)).powf(0.1))
} else {
self.radius
}
}
pub fn xuv_mass_loss_rate(&self, stellar_xuv_flux: f64) -> f64 {
let eta = 0.15;
let r_xuv = self.radius * 1.5;
let area = PI * r_xuv * r_xuv;
eta * stellar_xuv_flux * area * self.radius / (G * self.mass)
}
pub fn atmospheric_loss_timescale(&self, stellar_xuv_flux: f64) -> f64 {
let m_atm = 0.01 * self.mass;
let mdot = self.xuv_mass_loss_rate(stellar_xuv_flux);
if mdot > 0.0 {
m_atm / mdot
} else {
f64::INFINITY
}
}
pub fn tidal_migration_rate(&self, star_mass: f64, q_star: f64) -> f64 {
let a = self.semi_major;
let n = (G * star_mass / (a * a * a)).sqrt();
-9.0 / 2.0
* n
* (self.mass / star_mass)
* (star_mass / self.mass)
* (self.radius / a).powi(5)
/ q_star
}
pub fn orbital_circularization_time(&self, star_mass: f64, q_planet: f64) -> f64 {
let a = self.semi_major;
let n = (G * star_mass / (a * a * a)).sqrt();
2.0 / 63.0 * q_planet / n * (self.mass / star_mass) * (a / self.radius).powi(5)
}
pub fn impact_erosion_fraction(impact_velocity: f64, escape_velocity: f64) -> f64 {
let ratio = impact_velocity / escape_velocity;
if ratio > 1.0 {
0.5 * (1.0 - 1.0 / ratio)
} else {
0.0
}
}
}
pub fn runaway_greenhouse_distance(stellar_luminosity: f64) -> f64 {
(stellar_luminosity / (4.0 * PI * 340.0 * SIGMA_SB * 340.0_f64.powi(3))).sqrt()
}
pub fn maximum_greenhouse_distance(stellar_luminosity: f64) -> f64 {
(stellar_luminosity / (4.0 * PI * 175.0 * SIGMA_SB * 175.0_f64.powi(3))).sqrt()
}
pub fn heavy_bombardment_rate(age: f64) -> f64 {
let t0 = 4.0e9 * YEAR;
let peak = 3.9e9 * YEAR;
if age < t0 {
1e20 * (-(age - peak).abs() / (0.1e9 * YEAR)).exp()
} else {
1e14 * (-age / (1e9 * YEAR)).exp()
}
}