use blackholesfactory::config::parameters::*;
use blackholesfactory::types::binary::*;
use blackholesfactory::types::intermediate_mass::*;
use blackholesfactory::types::primordial::*;
use blackholesfactory::types::stellar_mass::*;
use blackholesfactory::types::supermassive::*;
#[test]
fn stellar_from_mass_in_range() {
let bh = StellarMassBlackHole::from_mass(21.2, 0.998);
let m = bh.mass_solar();
assert!((STELLAR_MASS_MIN_SOLAR..=STELLAR_MASS_MAX_SOLAR).contains(&m));
}
#[test]
fn stellar_from_collapse_mass_varies() {
let bh1 = StellarMassBlackHole::from_collapse(15.0, 0.5);
let bh2 = StellarMassBlackHole::from_collapse(50.0, 0.5);
assert!(bh2.mass_solar() > bh1.mass_solar());
}
#[test]
fn stellar_kick_velocity_positive() {
let bh = StellarMassBlackHole::from_collapse(25.0, 0.7);
assert!(bh.kick_velocity() > 0.0);
}
#[test]
fn stellar_x_ray_luminosity_positive() {
let bh = StellarMassBlackHole::from_mass(21.2, 0.998);
assert!(bh.x_ray_luminosity(0.01) > 0.0);
}
#[test]
fn stellar_tidal_disruption_radius_positive() {
let bh = StellarMassBlackHole::from_mass(21.2, 0.998);
let r = bh.tidal_disruption_radius(SOLAR_MASS, 6.957e8);
assert!(r > 0.0);
}
#[test]
fn stellar_gw_strain_positive() {
let bh = StellarMassBlackHole::from_mass(21.2, 0.998);
let dist = 6.85e3 * LIGHT_YEAR;
let h = bh.gravitational_wave_strain(10.0 * SOLAR_MASS, dist, 1e10);
assert!(h > 0.0);
}
#[test]
fn intermediate_new_mass_in_range() {
let bh = IntermediateMassBlackHole::new(2e4, 0.5, FormationChannel::RunawayMerger);
let m = bh.mass_solar();
assert!((INTERMEDIATE_MASS_MIN_SOLAR..=INTERMEDIATE_MASS_MAX_SOLAR).contains(&m));
}
#[test]
fn intermediate_from_runaway_merger() {
let bh = IntermediateMassBlackHole::from_runaway_merger(1e6);
let m = bh.mass_solar();
assert!((INTERMEDIATE_MASS_MIN_SOLAR..=INTERMEDIATE_MASS_MAX_SOLAR).contains(&m));
}
#[test]
fn intermediate_from_hierarchical_mergers() {
let bh = IntermediateMassBlackHole::from_hierarchical_mergers(50.0, 10);
let m = bh.mass_solar();
assert!(m >= INTERMEDIATE_MASS_MIN_SOLAR);
}
#[test]
fn intermediate_from_pop_iii() {
let bh = IntermediateMassBlackHole::from_pop_iii(500.0);
let m = bh.mass_solar();
assert!(m >= INTERMEDIATE_MASS_MIN_SOLAR);
}
#[test]
fn intermediate_qpo_frequency_positive() {
let bh = IntermediateMassBlackHole::new(2e4, 0.5, FormationChannel::RunawayMerger);
assert!(bh.ulf_qpo_frequency() > 0.0);
}
#[test]
fn intermediate_influence_radius_positive() {
let bh = IntermediateMassBlackHole::new(2e4, 0.5, FormationChannel::RunawayMerger);
assert!(bh.influence_radius(100e3) > 0.0);
}
#[test]
fn intermediate_merger_recoil_positive() {
let bh = IntermediateMassBlackHole::new(2e4, 0.5, FormationChannel::RunawayMerger);
assert!(bh.merger_recoil_velocity(0.5) > 0.0);
}
#[test]
fn supermassive_new_mass_in_range() {
let bh = SupermassiveBlackHole::new(6.5e9, 0.9, 375e3);
let m = bh.mass_solar();
assert!((SUPERMASSIVE_MASS_MIN_SOLAR..=SUPERMASSIVE_MASS_MAX_SOLAR).contains(&m));
}
#[test]
fn supermassive_from_m_sigma() {
let bh = SupermassiveBlackHole::from_m_sigma(200e3);
let m = bh.mass_solar();
assert!(m >= SUPERMASSIVE_MASS_MIN_SOLAR);
}
#[test]
fn supermassive_m_sigma_deviation_bounded() {
let bh = SupermassiveBlackHole::from_m_sigma(200e3);
assert!(bh.m_sigma_deviation() < 0.01);
}
#[test]
fn supermassive_eddington_positive() {
let bh = SupermassiveBlackHole::new(6.5e9, 0.9, 375e3);
assert!(bh.eddington_luminosity() > 0.0);
}
#[test]
fn supermassive_bondi_accretion_positive() {
let bh = SupermassiveBlackHole::new(6.5e9, 0.9, 375e3);
let mdot = bh.bondi_accretion_rate(1e-21, 1e6);
assert!(mdot > 0.0);
}
#[test]
fn supermassive_jet_power_positive() {
let bh = SupermassiveBlackHole::new(6.5e9, 0.9, 375e3);
assert!(bh.jet_power_estimate() > 0.0);
}
#[test]
fn supermassive_shadow_angular_diameter_reasonable() {
let bh = SupermassiveBlackHole::new(6.5e9, 0.9, 375e3);
let dist = 16.8e6 * PARSEC;
let d = bh.shadow_angular_diameter_uas(dist);
assert!(d > 10.0 && d < 100.0);
}
#[test]
fn supermassive_swallows_star_whole() {
let bh = SupermassiveBlackHole::new(6.5e9, 0.9, 375e3);
assert!(!bh.can_disrupt_star(SOLAR_MASS, 6.957e8));
}
#[test]
fn supermassive_inspiral_timescale_positive() {
let bh = SupermassiveBlackHole::new(6.5e9, 0.9, 375e3);
let t = bh.inspiral_timescale(1e4 * SOLAR_MASS, 0.1 * PARSEC);
assert!(t > 0.0);
}
#[test]
fn supermassive_dynamical_friction_positive() {
let bh = SupermassiveBlackHole::new(6.5e9, 0.9, 375e3);
let t = bh.dynamical_friction_timescale(1e4 * SOLAR_MASS, PARSEC, 375e3);
assert!(t > 0.0);
}
#[test]
fn primordial_new_mass_clamped() {
let bh = PrimordialBlackHole::new(1e12, PrimordialFormation::DensityFluctuation);
assert!((PRIMORDIAL_MASS_MIN_KG..=PRIMORDIAL_MASS_MAX_KG).contains(&bh.mass_kg()));
}
#[test]
fn primordial_hawking_temperature_positive() {
let bh = PrimordialBlackHole::new(1e12, PrimordialFormation::CosmicString);
assert!(bh.hawking_temperature() > 0.0);
}
#[test]
fn primordial_evaporation_time_finite() {
let bh = PrimordialBlackHole::new(1e12, PrimordialFormation::BubbleCollision);
let t = bh.evaporation_time();
assert!(t > 0.0 && t < f64::INFINITY);
}
#[test]
fn primordial_light_evaporates_fast() {
let bh = PrimordialBlackHole::new(1e8, PrimordialFormation::PhaseTransition);
assert!(bh.is_evaporated(UNIVERSE_AGE));
}
#[test]
fn primordial_heavy_survives() {
let bh = PrimordialBlackHole::new(1e12, PrimordialFormation::DomainWall);
assert!(!bh.is_evaporated(UNIVERSE_AGE));
}
#[test]
fn primordial_luminosity_positive() {
let bh = PrimordialBlackHole::new(1e12, PrimordialFormation::DensityFluctuation);
assert!(bh.luminosity() > 0.0);
}
#[test]
fn primordial_peak_emission_energy_positive() {
let bh = PrimordialBlackHole::new(1e12, PrimordialFormation::DensityFluctuation);
assert!(bh.peak_emission_energy() > 0.0);
}
#[test]
fn primordial_with_spin_builder() {
let bh = PrimordialBlackHole::new(1e15, PrimordialFormation::CosmicString).with_spin(0.5);
assert!((bh.singularity.spin - 0.5).abs() < 1e-10);
}
#[test]
fn primordial_with_formation_epoch() {
let bh = PrimordialBlackHole::new(1e12, PrimordialFormation::DensityFluctuation)
.with_formation_epoch(1e-23);
assert!((bh.formation_epoch - 1e-23).abs() < 1e-30);
}
#[test]
fn primordial_remaining_lifetime_decreases() {
let bh = PrimordialBlackHole::new(1e12, PrimordialFormation::PhaseTransition);
let early = bh.remaining_lifetime(0.0);
let later = bh.remaining_lifetime(1e50);
assert!(early > later);
}
#[test]
fn primordial_horizon_mass_at_epoch() {
let m = PrimordialBlackHole::horizon_mass_at_epoch(1e-5);
assert!(m > 0.0);
}
#[test]
fn binary_total_mass() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 35.0 * SOLAR_MASS, 1e9);
let expected = 65.0 * SOLAR_MASS;
assert!((bb.total_mass() - expected).abs() / expected < 1e-10);
}
#[test]
fn binary_chirp_mass_positive() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 35.0 * SOLAR_MASS, 1e9);
assert!(bb.chirp_mass() > 0.0);
}
#[test]
fn binary_orbital_period_positive() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9);
assert!(bb.orbital_period() > 0.0);
}
#[test]
fn binary_gw_frequency_positive() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9);
assert!(bb.gravitational_wave_frequency() > 0.0);
}
#[test]
fn binary_merger_timescale_positive() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9);
assert!(bb.merger_timescale() > 0.0);
}
#[test]
fn binary_eccentricity_slows_merger() {
let circ = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9);
let ecc =
BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9).with_eccentricity(0.8);
assert!(ecc.merger_timescale() < circ.merger_timescale());
}
#[test]
fn binary_gw_strain_positive() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9);
assert!(bb.gravitational_wave_strain(100e6 * PARSEC) > 0.0);
}
#[test]
fn binary_gw_luminosity_positive() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9);
assert!(bb.gravitational_wave_luminosity() > 0.0);
}
#[test]
fn binary_final_spin_bounded() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9);
let spin = bb.final_spin_estimate();
assert!(spin > 0.0 && spin <= 0.998);
}
#[test]
fn binary_final_mass_less_than_total() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9);
assert!(bb.final_mass_estimate() < bb.total_mass());
}
#[test]
fn binary_energy_radiated_positive() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9);
assert!(bb.energy_radiated() > 0.0);
}
#[test]
fn binary_with_spins_builder() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9).with_spins(0.7, 0.3);
assert!((bb.primary.spin - 0.7).abs() < 1e-10);
assert!((bb.secondary.spin - 0.3).abs() < 1e-10);
}
#[test]
fn binary_symmetric_mass_ratio_bounded() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9);
let eta = bb.symmetric_mass_ratio();
assert!(eta > 0.0 && eta <= 0.25);
}
#[test]
fn binary_orbital_velocity_positive() {
let bb = BinaryBlackHole::new(30.0 * SOLAR_MASS, 30.0 * SOLAR_MASS, 1e9);
assert!(bb.orbital_velocity() > 0.0);
}