use crate::config::parameters::{C, G, gravitational_radius, schwarzschild_radius};
pub struct Singularity {
pub mass: f64,
pub spin: f64,
pub charge: f64,
}
impl Singularity {
pub fn new(mass: f64) -> Self {
Self {
mass,
spin: 0.0,
charge: 0.0,
}
}
pub fn with_spin(mut self, spin: f64) -> Self {
self.spin = spin.clamp(-1.0, 1.0);
self
}
pub fn with_charge(mut self, charge: f64) -> Self {
self.charge = charge;
self
}
pub fn gravitational_radius(&self) -> f64 {
gravitational_radius(self.mass)
}
pub fn schwarzschild_radius(&self) -> f64 {
schwarzschild_radius(self.mass)
}
pub fn event_horizon(&self) -> f64 {
let rg = self.gravitational_radius();
let a = self.spin * rg;
let rq2 = G * self.charge * self.charge / (C * C * C * C);
rg + (rg * rg - a * a - rq2).max(0.0).sqrt()
}
pub fn cauchy_horizon(&self) -> f64 {
let rg = self.gravitational_radius();
let a = self.spin * rg;
let rq2 = G * self.charge * self.charge / (C * C * C * C);
rg - (rg * rg - a * a - rq2).max(0.0).sqrt()
}
pub fn ergosphere_radius(&self, theta: f64) -> f64 {
let rg = self.gravitational_radius();
let a = self.spin * rg;
rg + (rg * rg - a * a * theta.cos().powi(2)).max(0.0).sqrt()
}
pub fn is_naked(&self) -> bool {
let rg = self.gravitational_radius();
let a = self.spin * rg;
let rq2 = G * self.charge * self.charge / (C * C * C * C);
a * a + rq2 > rg * rg
}
pub fn surface_gravity(&self) -> f64 {
let rh = self.event_horizon();
let rg = self.gravitational_radius();
let a = self.spin * rg;
let r_inner = (rh * rh - a * a).max(0.0).sqrt();
if rh + r_inner < 1e-30 {
return 0.0;
}
(rh - rg) / (2.0 * rh * (rh + r_inner))
}
pub fn angular_momentum(&self) -> f64 {
self.spin * G * self.mass * self.mass / C
}
pub fn irreducible_mass(&self) -> f64 {
let a2 = self.spin * self.spin;
self.mass / 2.0_f64.sqrt() * (1.0 + (1.0 - a2).max(0.0).sqrt()).sqrt()
}
pub fn penrose_energy_extraction(&self) -> f64 {
(self.mass - self.irreducible_mass()) * C * C
}
pub fn entropy(&self) -> f64 {
use crate::config::parameters::{HBAR, K_B};
let rh = self.event_horizon();
let rg = self.gravitational_radius();
let a = self.spin * rg;
let area = 4.0 * std::f64::consts::PI * (rh * rh + a * a);
K_B * C * C * C * area / (4.0 * HBAR * G)
}
}