use marss::physics::collisions::*;
use marss::physics::orbit::*;
use marss::physics::rotation::*;
use marss::physics::tides::*;
#[test]
fn hellas_impactor_energy() {
let h = hellas_impactor();
assert!(
h.kinetic_energy_j() > 1e25,
"Hellas KE: {}",
h.kinetic_energy_j()
);
}
#[test]
fn typical_mars_crosser_exists() {
let t = typical_mars_crosser();
assert!(t.mass_kg > 0.0 && t.velocity_m_s > 0.0);
}
#[test]
fn iron_asteroid_denser() {
let stone = Impactor::asteroid(1000.0, 10.0);
let iron = Impactor::iron_asteroid(1000.0, 10.0);
assert!(iron.density_kg_m3 > stone.density_kg_m3, "Iron denser");
}
#[test]
fn kinetic_energy_mt() {
let imp = Impactor::asteroid(100.0, 15.0);
let mt = imp.kinetic_energy_mt();
assert!(mt > 0.0, "KE in MT: {mt}");
}
#[test]
fn impact_velocity_greater_than_approach() {
let imp = Impactor::asteroid(500.0, 10.0);
let vi = imp.impact_velocity();
assert!(vi >= imp.velocity_m_s, "Impact vel >= approach: {vi}");
}
#[test]
fn crater_diameter_positive() {
let imp = Impactor::asteroid(500.0, 10.0);
let d = imp.crater_diameter_m(2900.0);
assert!(d > 0.0, "Crater diameter > 0: {d}");
}
#[test]
fn fireball_radius_positive() {
let imp = hellas_impactor();
let r = imp.fireball_radius_m();
assert!(r > 0.0, "Fireball radius > 0: {r}");
}
#[test]
fn ejecta_volume_positive() {
let imp = Impactor::asteroid(500.0, 10.0);
let v = imp.ejecta_volume_m3(2900.0);
assert!(v > 0.0, "Ejecta vol > 0: {v}");
}
#[test]
fn ejecta_escape_fraction_bounded() {
let imp = Impactor::asteroid(500.0, 10.0);
let ef = imp.ejecta_escape_fraction();
assert!((0.0..=1.0).contains(&ef), "Escape fraction in [0,1]: {ef}");
}
#[test]
fn orbital_period_days() {
let o = MarsOrbit::new();
let p = o.orbital_period_days();
assert!((p - 687.0).abs() < 5.0, "Mars year ~687 days: {p}");
}
#[test]
fn perihelion_closer_than_aphelion() {
let o = MarsOrbit::new();
assert!(o.perihelion_m() < o.aphelion_m(), "Perihelion < aphelion");
}
#[test]
fn escape_velocity() {
let v = MarsOrbit::escape_velocity_at_surface();
assert!(v > 4900.0 && v < 5100.0, "Escape vel ~5000 m/s: {v}");
}
#[test]
fn orbital_period_seconds() {
let o = MarsOrbit::new();
let ps = o.orbital_period_s();
assert!(ps > 5.9e7, "Period > 59M s: {ps}");
}
#[test]
fn velocity_at_distance() {
let o = MarsOrbit::new();
let v = o.velocity_at_distance(o.perihelion_m());
assert!(v > 20_000.0, "Perihelion velocity > 20 km/s: {v}");
}
#[test]
fn specific_orbital_energy_negative() {
let o = MarsOrbit::new();
let e = o.specific_orbital_energy();
assert!(e < 0.0, "Bound orbit: {e}");
}
#[test]
fn specific_angular_momentum_positive() {
let o = MarsOrbit::new();
let h = o.specific_angular_momentum();
assert!(h > 0.0, "Angular momentum > 0: {h}");
}
#[test]
fn gravitational_force_sun() {
let o = MarsOrbit::new();
let f = o.gravitational_force_sun();
assert!(f > 0.0, "Sun gravity > 0: {f}");
}
#[test]
fn mean_orbital_velocity() {
let o = MarsOrbit::new();
let v = o.mean_orbital_velocity();
assert!(v > 20_000.0 && v < 30_000.0, "Mean vel ~24 km/s: {v}");
}
#[test]
fn true_anomaly_deg_range() {
let o = MarsOrbit::new();
let ta = o.true_anomaly_deg();
assert!((0.0..360.0).contains(&ta), "True anomaly in [0,360): {ta}");
}
#[test]
fn position_finite() {
let o = MarsOrbit::new();
let (x, y, z) = o.position();
assert!(x.is_finite() && y.is_finite() && z.is_finite());
}
#[test]
fn solar_irradiance_positive() {
let o = MarsOrbit::new();
let i = o.solar_irradiance();
assert!(i > 400.0 && i < 800.0, "Mars irradiance ~590: {i}");
}
#[test]
fn orbit_step_advances() {
let mut o = MarsOrbit::new();
let r1 = o.current_radius();
o.step(86400.0);
let r2 = o.current_radius();
assert!((r1 - r2).abs() > 0.0 || r1.is_finite());
}
#[test]
fn surface_velocity_equator() {
let r = MarsRotation::new();
let v = r.surface_velocity_at_latitude(0.0);
assert!(v > 200.0 && v < 300.0, "Equator velocity ~240 m/s: {v}");
}
#[test]
fn surface_velocity_pole_zero() {
let r = MarsRotation::new();
let v = r.surface_velocity_at_latitude(90.0);
assert!(v.abs() < 1.0, "Pole velocity ~0: {v}");
}
#[test]
fn coriolis_zero_equator() {
let r = MarsRotation::new();
let f = r.coriolis_parameter(0.0);
assert!(f.abs() < 1e-10, "Coriolis 0 at equator: {f}");
}
#[test]
fn moment_of_inertia_positive() {
let r = MarsRotation::new();
let moi = r.moment_of_inertia();
assert!(moi > 0.0, "MOI > 0: {moi}");
}
#[test]
fn rotational_kinetic_energy() {
let r = MarsRotation::new();
let ke = r.rotational_kinetic_energy();
assert!(ke > 0.0, "Rotational KE > 0: {ke}");
}
#[test]
fn angular_momentum_positive() {
let r = MarsRotation::new();
let am = r.angular_momentum();
assert!(am > 0.0, "Angular momentum > 0: {am}");
}
#[test]
fn precession_rate_small() {
let r = MarsRotation::new();
let pr = r.precession_rate_rad_per_year();
assert!(pr.abs() < 0.01, "Small precession rate: {pr}");
}
#[test]
fn solar_declination_bounded() {
let r = MarsRotation::new();
let d = r.solar_declination(90.0);
assert!(d.abs() <= 30.0, "Solar decl <= 30: {d}");
}
#[test]
fn day_length_equator_equinox() {
let r = MarsRotation::new();
let dl = r.day_length_hours(0.0, 0.0);
let sol_h = marss::SOL_S / 3600.0;
assert!((dl - sol_h / 2.0).abs() < sol_h / 2.0, "~12h: {dl}");
}
#[test]
fn solar_tide_acceleration() {
let t = SolarTide::at_mean_distance();
let a = t.tidal_acceleration();
assert!(a > 0.0, "Tidal accel > 0: {a}");
}
#[test]
fn perihelion_tide_stronger() {
let peri = SolarTide::at_perihelion();
let aph = SolarTide::at_aphelion();
assert!(
peri.tidal_acceleration() > aph.tidal_acceleration(),
"Perihelion > aphelion tide"
);
}
#[test]
fn tidal_bulge_height_small() {
let t = SolarTide::at_mean_distance();
let h = t.tidal_bulge_height();
assert!(h > 0.0 && h < 0.1, "Tiny bulge: {h}");
}
#[test]
fn gravitational_force_positive() {
let t = SolarTide::at_mean_distance();
let f = t.gravitational_force();
assert!(f > 0.0, "Grav force > 0: {f}");
}