General Relativity

Einstein's Masterpiece: Gravity is the curvature of spacetime. Mass-energy tells spacetime how to curve, and spacetime tells mass-energy how to move.

Chapter 19: Kerr Solution

The Kerr solution (1963) describes rotating black holes and is the most astrophysically relevant exact solution. All realistic black holes have angular momentum, making Kerr the proper description of observed black holes.

Boyer-Lindquist Coordinates

\( ds^2 = -\left(1 - \frac{r_s r}{\Sigma}\right)dt^2 - \frac{2r_s ra\sin^2\theta}{\Sigma}dt\,d\phi + \frac{\Sigma}{\Delta}dr^2 + \Sigma d\theta^2 + \frac{A\sin^2\theta}{\Sigma}d\phi^2 \)

Definitions

Σ = r² + a²cos²θ
Δ = r² - rsr + a²
A = (r² + a²)² - a²Δsin²θ
a = J/Mc (spin parameter)

Limits

a → 0: Schwarzschild
a = M: Extremal Kerr
a > M: Naked singularity (forbidden!)

Key Surfaces

Event Horizons

\( r_\pm = M \pm \sqrt{M^2 - a^2} \)

Outer (r+) and inner (r-) horizons

Ergosphere

\( r_E = M + \sqrt{M^2 - a^2\cos^2\theta} \)

Region between ergosphere and horizon: everything must rotate with the hole!

Ring Singularity

Σ = 0 ⟹ r = 0, θ = π/2 (a ring, not a point!)

Frame Dragging

The off-diagonal g term causes frame dragging: spacetime itself rotates around the black hole. Even zero angular momentum observers (ZAMOs) rotate!

\( \omega = -\frac{g_{t\phi}}{g_{\phi\phi}} = \frac{r_s ra}{A} \)

Angular velocity of locally non-rotating frames

Penrose Process

Energy can be extracted from a rotating black hole via the ergosphere. Maximum efficiency: 29% of rest mass (vs 6% for Schwarzschild ISCO).

Python: Kerr Horizons

#!/usr/bin/env python3
"""
kerr_horizons.py - Visualize Kerr black hole structure
Run: python3 kerr_horizons.py
"""
import numpy as np
import matplotlib.pyplot as plt

M = 1.0  # Mass

def horizon_radius(a, sign=1):
    """Event horizon radii: r_± = M ± sqrt(M² - a²)"""
    return M + sign * np.sqrt(M**2 - a**2)

def ergosphere_radius(a, theta):
    """Ergosphere radius: r_E = M + sqrt(M² - a²cos²θ)"""
    return M + np.sqrt(M**2 - a**2 * np.cos(theta)**2)

# Plot horizons vs spin
fig, axes = plt.subplots(1, 2, figsize=(14, 6))

# Horizon radii vs spin
ax1 = axes[0]
a_vals = np.linspace(0, M*0.99, 100)
r_plus = [horizon_radius(a, +1) for a in a_vals]
r_minus = [horizon_radius(a, -1) for a in a_vals]

ax1.plot(a_vals/M, np.array(r_plus)/M, 'b-', linewidth=2, label=r'$r_+$ (outer horizon)')
ax1.plot(a_vals/M, np.array(r_minus)/M, 'r-', linewidth=2, label=r'$r_-$ (inner horizon)')
ax1.axhline(y=2, color='gray', linestyle='--', alpha=0.5, label='Schwarzschild (a=0)')
ax1.axhline(y=1, color='green', linestyle=':', alpha=0.5, label='Extremal (a=M)')
ax1.set_xlabel('a/M (spin parameter)')
ax1.set_ylabel('r/M')
ax1.set_title('Kerr Horizon Radii')
ax1.legend()
ax1.grid(True, alpha=0.3)
ax1.set_xlim(0, 1)
ax1.set_ylim(0, 2.5)

# Cross-section of ergosphere
ax2 = axes[1]
a = 0.9 * M  # High spin
theta = np.linspace(0, 2*np.pi, 360)

# Outer horizon (constant radius)
r_h = horizon_radius(a, +1)
x_h = r_h * np.sin(theta)
z_h = r_h * np.cos(theta)

# Ergosphere (θ-dependent)
r_e = np.array([ergosphere_radius(a, t) for t in theta])
x_e = r_e * np.sin(theta)
z_e = r_e * np.cos(theta)

ax2.fill(x_e/M, z_e/M, color='lightblue', alpha=0.3, label='Ergosphere')
ax2.plot(x_e/M, z_e/M, 'b-', linewidth=2)
ax2.fill(x_h/M, z_h/M, color='black', alpha=0.8, label='Event horizon')
ax2.plot(x_h/M, z_h/M, 'k-', linewidth=2)

# Ring singularity
ax2.plot([a/M, -a/M], [0, 0], 'r.', markersize=10, label='Ring singularity')

ax2.set_xlabel('x/M')
ax2.set_ylabel('z/M')
ax2.set_title(f'Kerr Cross-Section (a = {a/M:.1f}M)')
ax2.set_aspect('equal')
ax2.legend()
ax2.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('kerr_structure.png', dpi=150)
plt.show()

# ISCO for different spins
print("Kerr Black Hole ISCO Radii:")
print("Spin (a/M)    ISCO (prograde)    ISCO (retrograde)")
for a_val in [0, 0.5, 0.9, 0.99, 0.999]:
    a = a_val * M
    # Prograde ISCO
    z1 = 1 + (1-a**2/M**2)**(1/3) * ((1+a/M)**(1/3) + (1-a/M)**(1/3))
    z2 = np.sqrt(3*a**2/M**2 + z1**2)
    r_isco_pro = M * (3 + z2 - np.sqrt((3-z1)*(3+z1+2*z2)))
    # Retrograde ISCO
    r_isco_ret = M * (3 + z2 + np.sqrt((3-z1)*(3+z1+2*z2)))
    print(f"  {a_val:.3f}          {r_isco_pro/M:.3f}M              {r_isco_ret/M:.3f}M")

print("\nPlot saved as 'kerr_structure.png'")

To Run:

python3 kerr_horizons.py