use earths::physics::collisions::{Impactor, chicxulubequivalent, tunguskaequivalent};
use earths::physics::orbit::{
ARGUMENTPERIHELIONDEG, ECCENTRICITY, EarthOrbit, INCLINATIONDEG, LONGITUDEASCENDINGNODEDEG,
SEMIMAJORAXIS,
};
use earths::physics::rotation::{
AXIALTILTDEG, AXIALTILTRAD, EarthRotation, PRECESSIONPERIODYEARS, SIDEREALDAYS, SOLARDAYS,
};
use earths::physics::tides::{
TidalForce, lunartosolartideratio, neaptideamplitude, springtideamplitude,
};
#[test]
fn orbitalperiodabout365days() {
let orbit = EarthOrbit::new();
let days = orbit.orbitalperioddays();
assert!((days - 365.25).abs() < 1.0);
}
#[test]
fn perihelioncloserthanaphelion() {
let orbit = EarthOrbit::new();
assert!(orbit.perihelionm() < orbit.aphelionm());
}
#[test]
fn velocityhigheratperihelion() {
let orbit = EarthOrbit::new();
let vperi = orbit.velocityatdistance(orbit.perihelionm());
let vaph = orbit.velocityatdistance(orbit.aphelionm());
assert!(vperi > vaph);
}
#[test]
fn orbital_energy_negative_bound() {
let orbit = EarthOrbit::new();
let e = orbit.specific_orbital_energy();
assert!(e < 0.0);
}
#[test]
fn angular_momentum_positive() {
let orbit = EarthOrbit::new();
let l = orbit.specific_angular_momentum();
assert!(l > 0.0);
}
#[test]
fn escape_velocity_about_11kms() {
let vesc = EarthOrbit::escape_velocity_at_surface();
let vkms = vesc / 1000.0;
assert!((vkms - 11.2).abs() < 0.5);
}
#[test]
fn gravitational_force_sun_positive() {
let orbit = EarthOrbit::new();
let f = orbit.gravitational_force_sun();
assert!(f > 3e22);
}
#[test]
fn current_radius_at_zero_anomaly() {
let orbit = EarthOrbit::new();
let r = orbit.current_radius();
let expected = orbit.perihelionm();
assert!((r - expected).abs() / expected < 1e-10);
}
#[test]
fn mean_orbital_velocity_about_30kms() {
let orbit = EarthOrbit::new();
let v = orbit.mean_orbital_velocity() / 1000.0;
assert!((v - 29.8).abs() < 1.0);
}
#[test]
fn orbitalconstantsvalid() {
const { assert!(SEMIMAJORAXIS > 1.49e11 && SEMIMAJORAXIS < 1.50e11) };
const { assert!(ECCENTRICITY > 0.0 && ECCENTRICITY < 0.1) };
const { assert!(INCLINATIONDEG < 1.0) };
const { assert!(LONGITUDEASCENDINGNODEDEG < 360.0) };
const { assert!(ARGUMENTPERIHELIONDEG > 0.0 && ARGUMENTPERIHELIONDEG < 360.0) };
}
#[test]
fn surfacevelocitymaxatequator() {
let rot = EarthRotation::new();
let veq = rot.surfacevelocityatlatitude(0.0);
let v45 = rot.surfacevelocityatlatitude(45.0);
let v90 = rot.surfacevelocityatlatitude(90.0);
assert!(veq > v45);
assert!(v45 > v90);
assert!((veq - 465.0).abs() < 5.0);
}
#[test]
fn centripetalaccelerationmaxatequator() {
let rot = EarthRotation::new();
let aeq = rot.centripetalaccelerationatlatitude(0.0);
let a45 = rot.centripetalaccelerationatlatitude(45.0);
assert!(aeq > a45);
assert!(aeq > 0.03);
}
#[test]
fn coriolisparameterzeroatequator() {
let rot = EarthRotation::new();
let f = rot.coriolisparameter(0.0);
assert!(f.abs() < 1e-10);
}
#[test]
fn momentofinertiacorrectorder() {
let rot = EarthRotation::new();
let i = rot.momentofinertia();
assert!(i > 8e37 && i < 9e37);
}
#[test]
fn rotationalkineticenergyhuge() {
let rot = EarthRotation::new();
let ke = rot.rotationalkineticenergy();
assert!(ke > 2e29);
}
#[test]
fn angular_momentum_conserved_sign() {
let rot = EarthRotation::new();
let l = rot.angular_momentum();
assert!(l > 0.0);
}
#[test]
fn precessionratesmall() {
let rot = EarthRotation::new();
let rate = rot.precession_rate_rad_per_year();
assert!(rate > 0.0);
assert!(rate < 0.001);
}
#[test]
fn daylengthsummerlongerthanwinter() {
let rot = EarthRotation::new();
let summer = rot.day_length_variation_due_to_tilt(172, 50.0);
let winter = rot.day_length_variation_due_to_tilt(355, 50.0);
assert!(summer > winter);
assert!(summer > 12.0);
assert!(winter < 12.0);
}
#[test]
fn polarday24hours() {
let rot = EarthRotation::new();
let arcticsummer = rot.day_length_variation_due_to_tilt(172, 80.0);
assert!((arcticsummer - 24.0).abs() < 0.1);
}
#[test]
fn rotationconstantsvalid() {
const { assert!(SIDEREALDAYS < SOLARDAYS) };
assert!((AXIALTILTDEG - 23.44).abs() < 0.1);
assert!((AXIALTILTRAD - AXIALTILTDEG.to_radians()).abs() < 0.01);
const { assert!(PRECESSIONPERIODYEARS > 25000.0) };
}
#[test]
fn lunartidelargerthansolar() {
let moon = TidalForce::frommoon();
let sun = TidalForce::fromsun();
assert!(moon.tidalacceleration() > sun.tidalacceleration());
}
#[test]
fn tidalratioabout22() {
let ratio = lunartosolartideratio();
assert!((ratio - 2.2).abs() < 0.5);
}
#[test]
fn springtidelargerthanneap() {
let spring = springtideamplitude();
let neap = neaptideamplitude();
assert!(spring > neap);
assert!(spring > 0.0);
assert!(neap > 0.0);
}
#[test]
fn tidalpotentialvarieswithangle() {
let moon = TidalForce::frommoon();
let pot0 = moon.tidalpotential(0.0);
let pot90 = moon.tidalpotential(std::f64::consts::FRAC_PI_2);
assert!(pot0 != pot90);
}
#[test]
fn tidalbulgeheightpositive() {
let moon = TidalForce::frommoon();
let h = moon.tidalbulgeheight();
assert!(h > 0.0);
assert!(h < 1.0);
}
#[test]
fn gravitationalattractionmoonpositive() {
let moon = TidalForce::frommoon();
let f = moon.gravitationalattraction();
assert!(f > 1e20);
}
#[test]
fn gravitationalattractionsunmuchlarger() {
let moon = TidalForce::frommoon();
let sun = TidalForce::fromsun();
assert!(sun.gravitationalattraction() > moon.gravitationalattraction());
}
#[test]
fn chicxulubenormousenergy() {
let chix = chicxulubequivalent();
let energymt = chix.kineticenergymt();
assert!(energymt > 1e6);
}
#[test]
fn tunguskasmallerthanchicxulub() {
let tung = tunguskaequivalent();
let chix = chicxulubequivalent();
assert!(tung.kineticenergyj() < chix.kineticenergyj());
}
#[test]
fn impactvelocityhigherthanapproach() {
let imp = Impactor::asteroid(1000.0, 15.0);
let vimpact = imp.impactvelocity();
assert!(vimpact > imp.velocityms);
}
#[test]
fn craterdiameterincreaseswithimpactorsize() {
let small = Impactor::asteroid(100.0, 20.0);
let large = Impactor::asteroid(10000.0, 20.0);
let csmall = small.craterdiameterm(2700.0);
let clarge = large.craterdiameterm(2700.0);
assert!(clarge > csmall);
}
#[test]
fn fireballradiuspositive() {
let imp = Impactor::asteroid(500.0, 18.0);
let r = imp.fireballradiusm();
assert!(r > 0.0);
}
#[test]
fn ejectavolumepositive() {
let imp = Impactor::asteroid(1000.0, 20.0);
let vol = imp.ejectavolumem3(2700.0);
assert!(vol > 0.0);
}
#[test]
fn kineticenergymegatonsconsistent() {
let imp = Impactor::asteroid(500.0, 15.0);
let j = imp.kineticenergyj();
let mt = imp.kineticenergymt();
assert!((mt - j / 4.184e15).abs() < 1.0);
}