use crate::config::parameters::{PI, YEAR};
pub fn mantle_growth_per_orbit(
nucleus_radius: f64,
active_fraction: f64,
dust_to_gas: f64,
period_years: f64,
) -> f64 {
let area = 4.0 * PI * nucleus_radius * nucleus_radius * active_fraction;
let erosion_rate_m_per_s = 1.0e-9;
let dust_retention = dust_to_gas / (1.0 + dust_to_gas);
let growth = erosion_rate_m_per_s * dust_retention * period_years * YEAR;
growth * area / (4.0 * PI * nucleus_radius * nucleus_radius)
}
pub fn radius_loss_per_orbit(
dm_dt_perihelion: f64,
period_years: f64,
nucleus_radius: f64,
density: f64,
) -> f64 {
let area = 4.0 * PI * nucleus_radius * nucleus_radius;
if area < 1.0 || density < 1.0 {
return 0.0;
}
dm_dt_perihelion * period_years * YEAR / (area * density)
}
pub fn orbits_to_exhaustion(nucleus_radius: f64, radius_loss_per_pass: f64) -> f64 {
if radius_loss_per_pass < 1.0e-30 {
return f64::INFINITY;
}
nucleus_radius / radius_loss_per_pass
}
pub fn spinup_timescale(
nucleus_radius: f64,
density: f64,
rotation_period_s: f64,
dm_dt: f64,
gas_velocity: f64,
) -> f64 {
let mass = (4.0 / 3.0) * PI * nucleus_radius.powi(3) * density;
let inertia = 0.4 * mass * nucleus_radius * nucleus_radius;
let omega = 2.0 * PI / rotation_period_s;
let moment_arm = 0.01;
let torque = dm_dt * gas_velocity * nucleus_radius * moment_arm;
if torque < 1.0e-30 {
return f64::INFINITY;
}
inertia * omega / torque
}
pub fn splitting_risk(perihelion_au: f64, rotation_period_s: f64) -> f64 {
let q_factor = if perihelion_au < 1.0 {
(1.0 / perihelion_au.max(0.01)).sqrt()
} else {
1.0 / perihelion_au
};
let p_factor = if rotation_period_s < 7200.0 {
7200.0 / rotation_period_s.max(100.0)
} else {
1.0
};
(q_factor * p_factor).min(1.0)
}
pub fn brightness_fading(passages: f64, half_life_passages: f64) -> f64 {
if half_life_passages < 1.0e-10 {
return 0.0;
}
(-passages * (2.0_f64).ln() / half_life_passages).exp()
}