sagittariusas 0.0.1

Simulation engine for Sagittarius A* — Kerr spacetime, accretion, jets, lensing, and shadow observables
Documentation
use crate::config::parameters::{C, G};
use std::f64::consts::PI;

#[derive(Debug, Clone)]
pub struct BlackHoleShadow {
    pub mass: f64,
    pub spin: f64,
    pub inclination: f64,
}

impl BlackHoleShadow {
    pub fn new(mass: f64, spin: f64, inclination: f64) -> Self {
        Self {
            mass,
            spin,
            inclination,
        }
    }

    pub fn critical_impact_parameter(&self) -> f64 {
        let rs = sciforge::hub::prelude::astronomy::stellar::schwarzschild_radius(self.mass);
        if self.spin.abs() < 1e-12 {
            return 1.5 * rs * 3.0_f64.sqrt();
        }
        let rg = rs / 2.0;
        let a = self.spin * rg;
        3.0 * rg * 3.0_f64.sqrt() * (1.0 - a * a / (9.0 * rg * rg))
    }

    pub fn shadow_angular_radius(&self, distance: f64) -> f64 {
        self.critical_impact_parameter() / distance
    }

    pub fn shadow_contour(&self, n_points: usize) -> Vec<(f64, f64)> {
        let rs = sciforge::hub::prelude::astronomy::stellar::schwarzschild_radius(self.mass);
        let rg = rs / 2.0;
        let a = self.spin * rg;
        let sin_i = self.inclination.sin();
        let mut contour = Vec::with_capacity(n_points);
        for i in 0..n_points {
            let phi = 2.0 * PI * i as f64 / n_points as f64;
            let b_crit = self.critical_impact_parameter();
            let displacement = a * sin_i * phi.cos();
            let alpha = (b_crit + displacement) * phi.sin();
            let beta = (b_crit + 0.5 * displacement) * phi.cos();
            contour.push((alpha / rg, beta / rg));
        }
        contour
    }

    pub fn asymmetry_parameter(&self) -> f64 {
        let rs = 2.0 * G * self.mass / (C * C);
        let rg = rs / 2.0;
        let a = self.spin * rg;
        2.0 * a * self.inclination.sin() / self.critical_impact_parameter()
    }

    pub fn shadow_area(&self) -> f64 {
        let b_crit = self.critical_impact_parameter();
        PI * b_crit * b_crit
    }

    pub fn photon_ring_radius(&self) -> f64 {
        let rs = sciforge::hub::prelude::astronomy::stellar::schwarzschild_radius(self.mass);
        1.5 * rs
    }

    pub fn shadow_diameter_uas(&self, distance: f64) -> f64 {
        let angular_radius = self.shadow_angular_radius(distance);
        let uas_per_rad = 206_265.0 * 1e6;
        2.0 * angular_radius * uas_per_rad
    }
}

pub fn eht_expected_diameter_uas() -> f64 {
    use crate::config::parameters::{SGR_A_DISTANCE, SGR_A_MASS, SGR_A_SPIN};
    let shadow = BlackHoleShadow::new(SGR_A_MASS, SGR_A_SPIN, PI / 3.0);
    shadow.shadow_diameter_uas(SGR_A_DISTANCE)
}