use crate::config::parameters::*;
pub struct MetallicAsteroid {
pub radius: f64,
pub density: f64,
pub mass: f64,
pub iron_fraction: f64,
pub nickel_fraction: f64,
pub semi_major_axis: f64,
pub eccentricity: f64,
pub albedo: f64,
pub radar_albedo: f64,
pub thermal_inertia: f64,
}
impl MetallicAsteroid {
pub fn new(radius_m: f64, iron_fraction: f64) -> Self {
let radius = radius_m.clamp(MIN_ASTEROID_RADIUS, MAX_ASTEROID_RADIUS);
let iron_fraction = iron_fraction.clamp(0.3, 0.95);
let nickel_fraction = (1.0 - iron_fraction) * 0.3;
let density = 3500.0 + 4500.0 * iron_fraction;
let mass = sphere_mass(radius, density);
Self {
radius,
density,
mass,
iron_fraction,
nickel_fraction,
semi_major_axis: 2.7,
eccentricity: 0.15,
albedo: 0.12,
radar_albedo: 0.30 + 0.20 * iron_fraction,
thermal_inertia: 100.0 + 300.0 * iron_fraction,
}
}
pub fn with_orbit(mut self, semi_major_au: f64, ecc: f64) -> Self {
self.semi_major_axis = semi_major_au.max(0.1);
self.eccentricity = ecc.clamp(0.0, 0.999);
self
}
pub fn with_nickel_fraction(mut self, ni: f64) -> Self {
self.nickel_fraction = ni.clamp(0.01, 1.0 - self.iron_fraction);
self
}
pub fn surface_gravity(&self) -> f64 {
surface_gravity(self.mass, self.radius)
}
pub fn escape_velocity(&self) -> f64 {
escape_velocity(self.mass, self.radius)
}
pub fn orbital_period(&self) -> f64 {
orbital_period(self.semi_major_axis, SOLAR_MASS)
}
pub fn orbital_period_years(&self) -> f64 {
self.orbital_period() / YEAR
}
pub fn metal_content_mass(&self) -> f64 {
self.mass * (self.iron_fraction + self.nickel_fraction)
}
pub fn silicate_fraction(&self) -> f64 {
1.0 - self.iron_fraction - self.nickel_fraction
}
pub fn is_differentiated(&self) -> bool {
self.radius > 50000.0
}
pub fn core_radius_estimate(&self) -> f64 {
self.radius * self.iron_fraction.powf(1.0 / 3.0)
}
pub fn magnetic_remanence_possible(&self) -> bool {
self.iron_fraction > 0.5 && self.radius > 10000.0
}
pub fn thermal_conductivity_estimate(&self) -> f64 {
10.0 + 50.0 * self.iron_fraction
}
pub fn absolute_magnitude(&self) -> f64 {
let diameter_km = 2.0 * self.radius / 1000.0;
15.618 - 5.0 * diameter_km.log10() - 2.5 * self.albedo.log10()
}
pub fn equilibrium_temperature(&self) -> f64 {
equilibrium_temperature(SOLAR_LUMINOSITY, self.semi_major_axis * AU, self.albedo)
}
}