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 gtφ 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