Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download

SageMath notebooks associated to the Black Hole Lectures (https://luth.obspm.fr/~luthier/gourgoulhon/bh16)

Project: BHLectures
Views: 20113
Kernel: SageMath 9.2

Spherical null geodesics in Kerr spacetime

Computation with kerrgeodesic_gw

This Jupyter/SageMath notebook is relative to the lectures Geometry and physics of black holes.

It requires SageMath (version \geq 8.2), with the package kerrgeodesic_gw (version \geq 0.3.2). To install the latter, simply run

sage -pip install kerrgeodesic_gw

in a terminal.

version()
'SageMath version 9.2, Release Date: 2020-10-24'

First, we set up the notebook to use LaTeX-formatted display:

%display latex

and we ask for CPU demanding computations to be performed in parallel on 8 processes:

Parallelism().set(nproc=8)

A Kerr black bole is entirely defined by two parameters (m,a)(m, a), where mm is the black hole mass and aa is the black hole angular momentum divided by mm. In this notebook, we shall set m=1m=1 and we denote the angular momentum parameter aa by the symbolic variable a, using a0 for a specific numerical value:

a = var('a') a0 = 0.95

The spacetime object is created as an instance of the class KerrBH:

from kerrgeodesic_gw import KerrBH M = KerrBH(a) print(M)
Kerr spacetime M

The Boyer-Lindquist coordinate rr of the event horizon:

rH = M.event_horizon_radius() rH
a2+1+1\renewcommand{\Bold}[1]{\mathbf{#1}}\sqrt{-a^{2} + 1} + 1
rH0 = rH.subs({a: a0}) show(LatexExpr(r'r_+ = '), rH0)
r+=1.31224989991992\renewcommand{\Bold}[1]{\mathbf{#1}}r_+ = 1.31224989991992
show(LatexExpr(r'r_- = '), M.inner_horizon_radius().subs({a: a0}))
r=0.687750100080080\renewcommand{\Bold}[1]{\mathbf{#1}}r_- = 0.687750100080080

The method boyer_lindquist_coordinates() returns the chart of Boyer-Lindquist coordinates BL and allows the user to instanciate the Python variables (t, r, th, ph) to the coordinates (t,r,θ,ϕ)(t,r,\theta,\phi):

BL.<t, r, th, ph> = M.boyer_lindquist_coordinates() BL
(M,(t,r,θ,ϕ))\renewcommand{\Bold}[1]{\mathbf{#1}}\left(M,(t, r, {\theta}, {\phi})\right)

The metric tensor is naturally returned by the method metric():

g = M.metric() g.display()
g=(a2cos(θ)2+r22ra2cos(θ)2+r2)dtdt+(2arsin(θ)2a2cos(θ)2+r2)dtdϕ+(a2cos(θ)2+r2a2+r22r)drdr+(a2cos(θ)2+r2)dθdθ+(2arsin(θ)2a2cos(θ)2+r2)dϕdt+(2a2rsin(θ)4+(a2r2+r4+(a4+a2r2)cos(θ)2)sin(θ)2a2cos(θ)2+r2)dϕdϕ\renewcommand{\Bold}[1]{\mathbf{#1}}g = \left( -\frac{a^{2} \cos\left({\theta}\right)^{2} + r^{2} - 2 \, r}{a^{2} \cos\left({\theta}\right)^{2} + r^{2}} \right) \mathrm{d} t\otimes \mathrm{d} t + \left( -\frac{2 \, a r \sin\left({\theta}\right)^{2}}{a^{2} \cos\left({\theta}\right)^{2} + r^{2}} \right) \mathrm{d} t\otimes \mathrm{d} {\phi} + \left( \frac{a^{2} \cos\left({\theta}\right)^{2} + r^{2}}{a^{2} + r^{2} - 2 \, r} \right) \mathrm{d} r\otimes \mathrm{d} r + \left( a^{2} \cos\left({\theta}\right)^{2} + r^{2} \right) \mathrm{d} {\theta}\otimes \mathrm{d} {\theta} + \left( -\frac{2 \, a r \sin\left({\theta}\right)^{2}}{a^{2} \cos\left({\theta}\right)^{2} + r^{2}} \right) \mathrm{d} {\phi}\otimes \mathrm{d} t + \left( \frac{2 \, a^{2} r \sin\left({\theta}\right)^{4} + {\left(a^{2} r^{2} + r^{4} + {\left(a^{4} + a^{2} r^{2}\right)} \cos\left({\theta}\right)^{2}\right)} \sin\left({\theta}\right)^{2}}{a^{2} \cos\left({\theta}\right)^{2} + r^{2}} \right) \mathrm{d} {\phi}\otimes \mathrm{d} {\phi}

Spherical photon orbits

Functions (r0)\ell(r_0) and q(r0)q(r_0) for spherical photon orbits:

r = var('r') lsph(a, r) = (r^2*(3 - r) - a^2*(r + 1))/(a*(r -1)) lsph
(a,r)  a2(r+1)+(r3)r2a(r1)\renewcommand{\Bold}[1]{\mathbf{#1}}\left( a, r \right) \ {\mapsto} \ -\frac{a^{2} {\left(r + 1\right)} + {\left(r - 3\right)} r^{2}}{a {\left(r - 1\right)}}
qsph(a, r) = r^3 / (a^2*(r - 1)^2) * (4*a^2 - r*(r - 3)^2) qsph
(a,r)  ((r3)2r4a2)r3a2(r1)2\renewcommand{\Bold}[1]{\mathbf{#1}}\left( a, r \right) \ {\mapsto} \ -\frac{{\left({\left(r - 3\right)}^{2} r - 4 \, a^{2}\right)} r^{3}}{a^{2} {\left(r - 1\right)}^{2}}

θ\theta-turning points:

theta0(a, l, q) = arccos(sqrt(1/2*(1 - (l^2+q)/a^2 + sqrt((1 - (l^2+q)/a^2)^2 + 4*q/a^2)))) theta0
(a,l,q)  arccos(12(l2+qa21)2+4qa2l2+q2a2+12)\renewcommand{\Bold}[1]{\mathbf{#1}}\left( a, l, q \right) \ {\mapsto} \ \arccos\left(\sqrt{\frac{1}{2} \, \sqrt{{\left(\frac{l^{2} + q}{a^{2}} - 1\right)}^{2} + \frac{4 \, q}{a^{2}}} - \frac{l^{2} + q}{2 \, a^{2}} + \frac{1}{2}}\right)
theta1(a, l, q) = arccos(sqrt(1/2*(1 - (l^2+q)/a^2 - sqrt((1 - (l^2+q)/a^2)^2 + 4*q/a^2)))) theta1
(a,l,q)  arccos(12(l2+qa21)2+4qa2l2+q2a2+12)\renewcommand{\Bold}[1]{\mathbf{#1}}\left( a, l, q \right) \ {\mapsto} \ \arccos\left(\sqrt{-\frac{1}{2} \, \sqrt{{\left(\frac{l^{2} + q}{a^{2}} - 1\right)}^{2} + \frac{4 \, q}{a^{2}}} - \frac{l^{2} + q}{2 \, a^{2}} + \frac{1}{2}}\right)

Spherical photon orbit at r0=3mr_0 = 3 m (q=qmax=27m2q = q_{\rm max} = 27 m^2)

r0 = 3. E = 1 L = lsph(a0, r0) Q = qsph(a0, r0) L, Q
(1.90000000000000,27.0000000000000)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(-1.90000000000000, 27.0000000000000\right)
theta0(a0, L, Q)
0.345877348029357\renewcommand{\Bold}[1]{\mathbf{#1}}0.345877348029357
P = M.point((0, r0, pi/2, 0), name='P') print(P)
Point P on the Kerr spacetime M

A geodesic is constructed by providing the range [λmin,λmax][\lambda_{\rm min},\lambda_{\rm max}] of the affine parameter λ\lambda, the initial point and either

  • (i) the Boyer-Lindquist components (p0t,p0r,p0θ,p0ϕ)(p^t_0, p^r_0, p^\theta_0, p^\phi_0) of the initial 4-momentum vector p0=dxdλλminp_0 = \left. \frac{\mathrm{d}x}{\mathrm{d}\lambda}\right| _{\lambda_{\rm min}},

  • (ii) the four integral of motions (μ,E,L,Q)(\mu, E, L, Q)

  • or (iii) some of the components of p0p_0 along with with some integrals of motion.

lmax = 100 # lambda_max
Li = M.geodesic([0, lmax], P, mu=0, E=E, L=L, Q=Q, a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=3.00000000000000t+(9.36596633575423×109)r+0.577350269189626θ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 3.00000000000000 \frac{\partial}{\partial t } + \left( 9.36596633575423 \times 10^{-9} \right) \frac{\partial}{\partial r } + 0.577350269189626 \frac{\partial}{\partial {\theta} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
v0 = Li.initial_tangent_vector() Li = M.geodesic([0, lmax], P, pt0=v0[0], pr0=0, pth0=v0[2], pph0=v0[3], a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=3.00000000000000t+0.577350269189626θ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 3.00000000000000 \frac{\partial}{\partial t } + 0.577350269189626 \frac{\partial}{\partial {\theta} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].

The numerical integration of the geodesic equation is performed via integrate(), by providing the integration step δλ\delta\lambda:

Li.integrate(step=0.001, method='dopri5') Li.check_integrals_of_motion(0.999*lmax)
quantity value initial value diff. relative diff.
-
print("Final point: ") show(BL[:], "=", BL(Li(0.999*lmax)))
Final point:
(t,r,θ,ϕ)=(291.1717434701057,3.0,2.144493861874287,39.55667803565552)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(t, r, {\theta}, {\phi}\right) \verb|=| \left(291.1717434701057, 3.0, 2.144493861874287, -39.55667803565552\right)
lplot = 0.32*lmax print("max lambda (plot): ", lplot) Li.plot(prange=(0, lplot), plot_points=2000, thickness=3, color='green', display_tangent=True, scale=0.15, width_tangent=2, color_tangent='green', plot_points_tangent=20, horizon_color='lightgrey') \ + line([(0,0,-3), (0,0,3)], color='black', thickness=2)
max lambda (plot): 32.0000000000000
graph = Li.plot(coordinates='xy', prange=(0, lplot), plot_points=2000, thickness=3, color='green', display_tangent=True, scale=0.15, width_tangent=2, color_tangent='green', plot_points_tangent=20, horizon_color='lightgrey', axes_labels=[r'$x/m$', r'$y/m$']) graph.save("gik_spher_3d_r_30_xy.pdf") graph
Image in a Jupyter notebook
Li.plot(coordinates='xz', prange=(0, lplot), plot_points=2000, thickness=3, color='green', display_tangent=True, scale=0.15, width_tangent=2, color_tangent='green', plot_points_tangent=20, horizon_color='lightgrey', axes_labels=[r'$x/m$', r'$z/m$'])
Image in a Jupyter notebook

Prograde spherical photon orbit at r0=1.6mr_0 = 1.6m

r0 = 1.6 L = lsph(a0, r0) Q = qsph(a0, r0) L, Q
(2.17105263157895,5.97569713758080)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(2.17105263157895, 5.97569713758080\right)
theta0(a0, L, Q)
0.705442812649839\renewcommand{\Bold}[1]{\mathbf{#1}}0.705442812649839
P = M.point((0, r0, pi/2, 0), name='P') lmax = 70 Li = M.geodesic([0, lmax], P, mu=0, E=E, L=L, Q=Q, a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=7.66666666666666t+(1.74608999691187×1024+2.85158136717879×108i)r+0.954892151626195θ+2.45614035087719ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 7.66666666666666 \frac{\partial}{\partial t } + \left( 1.74608999691187 \times 10^{-24} + 2.85158136717879 \times 10^{-8}i \right) \frac{\partial}{\partial r } + 0.954892151626195 \frac{\partial}{\partial {\theta} } + 2.45614035087719 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
v0 = Li.initial_tangent_vector() Li = M.geodesic([0, lmax], P, pt0=v0[0], pr0=0, pth0=v0[2], pph0=v0[3], a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=7.66666666666666t+0.954892151626195θ+2.45614035087719ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 7.66666666666666 \frac{\partial}{\partial t } + 0.954892151626195 \frac{\partial}{\partial {\theta} } + 2.45614035087719 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
Li.integrate(step=0.0004, method='dopri5') Li.check_integrals_of_motion(0.999*lmax)
quantity value initial value diff. relative diff.
print("Final point: ") show(BL[:], "=", BL(Li(0.999*lmax)))
Final point:
(t,r,θ,ϕ)=(492.9599102672748,1.599974600261711,0.8276182451833887,185.0198306183178)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(t, r, {\theta}, {\phi}\right) \verb|=| \left(492.9599102672748, 1.599974600261711, 0.8276182451833887, 185.0198306183178\right)
lplot = 0.11*lmax print("max lambda (plot): ", lplot) Li.plot(prange=(0, lplot), plot_points=2000, thickness=3, color='green', display_tangent=True, scale=0.03, width_tangent=1, color_tangent='green', plot_points_tangent=20, horizon_color='lightgrey') \ + line([(0,0,-1.5), (0,0,1.5)], color='black', thickness=2)
max lambda (plot): 7.70000000000000
Li.plot(prange=(0, lmax), plot_points=2000, thickness=3, color='green', display_tangent=True, scale=0.03, width_tangent=1, color_tangent='green', plot_points_tangent=40, horizon_color='lightgrey') \ + line([(0,0,-1.5), (0,0,1.5)], color='black', thickness=2)

Spherical photon orbit at r0=2.8mr_0=2.8m

r0 = 2.8 L = lsph(a0, r0) Q = qsph(a0, r0) L, Q
(1.08859649122807,26.2604206422489)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(-1.08859649122807, 26.2604206422489\right)
theta0(a0, L, Q)
0.206050206829550\renewcommand{\Bold}[1]{\mathbf{#1}}0.206050206829550
P = M.point((0, r0, pi/2, 0), name='P') lmax = 100 Li = M.geodesic([0, lmax], P, mu=0, E=E, L=L, Q=Q, a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=3.22222222222222t+(4.65527024480212×1025+7.60263326216718×109i)r+0.653634213345212θ+0.116959064327486ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 3.22222222222222 \frac{\partial}{\partial t } + \left( 4.65527024480212 \times 10^{-25} + 7.60263326216718 \times 10^{-9}i \right) \frac{\partial}{\partial r } + 0.653634213345212 \frac{\partial}{\partial {\theta} } + 0.116959064327486 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
v0 = Li.initial_tangent_vector() Li = M.geodesic([0, lmax], P, pt0=v0[0], pr0=0, pth0=v0[2], pph0=v0[3], a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=3.22222222222222t+0.653634213345212θ+0.116959064327486ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 3.22222222222222 \frac{\partial}{\partial t } + 0.653634213345212 \frac{\partial}{\partial {\theta} } + 0.116959064327486 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
Li.integrate(step=0.001, method='dopri5') Li.check_integrals_of_motion(0.999*lmax)
quantity value initial value diff. relative diff.
print("Final point: ") show(BL[:], "=", BL(Li(0.999*lmax)))
Final point:
(t,r,θ,ϕ)=(310.4228769082733,2.8,2.462502125969338,39.07005458983995)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(t, r, {\theta}, {\phi}\right) \verb|=| \left(310.4228769082733, 2.8, 2.462502125969338, -39.07005458983995\right)
lplot = 0.38*lmax print("max lambda (plot): ", lplot) Li.plot(prange=(0, lplot), plot_points=2000, thickness=3, color='green', display_tangent=True, scale=0.12, width_tangent=2, color_tangent='green', plot_points_tangent=20, horizon_color='lightgrey')
max lambda (plot): 38.0000000000000
graph = Li.plot(coordinates='xy', prange=(0, lplot), plot_points=2000, thickness=3, color='green', display_tangent=True, scale=0.01, width_tangent=1, color_tangent='green', plot_points_tangent=20, horizon_color='lightgrey', axes_labels=[r'$x/m$', r'$y/m$']) graph.save("gik_spher_3d_r_28_xy.pdf") graph
Image in a Jupyter notebook
Li.plot(coordinates='txy', prange=(0, lplot), plot_points=2000, thickness=3, color='green', display_tangent=True, scale=0.2, width_tangent=2, color_tangent='green', plot_points_tangent=20, horizon_color='lightgrey')

Retrograde spherical photon orbit at r0=3.9mr_0 = 3.9 m

r0 = 3.9 L = lsph(a0, r0) Q = qsph(a0, r0) L, Q
(6.57395644283122,3.52474056409564)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(-6.57395644283122, 3.52474056409564\right)
theta0(a0, L, Q)
1.29003447185548\renewcommand{\Bold}[1]{\mathbf{#1}}1.29003447185548
P = M.point((0, r0, pi/2, 0), name='P')
lmax = 100 Li = M.geodesic([0, lmax], P, mu=0, E=E, L=L, Q=Q, a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=2.37931034482759t+(2.22112222707613×108)r+0.123433875307859θ0.326678765880218ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 2.37931034482759 \frac{\partial}{\partial t } + \left( 2.22112222707613 \times 10^{-8} \right) \frac{\partial}{\partial r } + 0.123433875307859 \frac{\partial}{\partial {\theta} } -0.326678765880218 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
v0 = Li.initial_tangent_vector() Li = M.geodesic([0, lmax], P, pt0=v0[0], pr0=0, pth0=v0[2], pph0=v0[3], a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=2.37931034482759t+0.123433875307859θ0.326678765880218ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 2.37931034482759 \frac{\partial}{\partial t } + 0.123433875307859 \frac{\partial}{\partial {\theta} } -0.326678765880218 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
Li.integrate(step=0.001, method='dopri5') Li.check_integrals_of_motion(0.999*lmax)
quantity value initial value diff. relative diff.
print("Final point: ") show(BL[:], "=", BL(Li(0.999*lmax)))
Final point:
(t,r,θ,ϕ)=(237.38270015383975,3.9,1.6881755637536546,34.301693666892874)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(t, r, {\theta}, {\phi}\right) \verb|=| \left(237.38270015383975, 3.9, 1.6881755637536546, -34.301693666892874\right)
lplot = 0.55*lmax print("max lambda (plot): ", lplot) Li.plot(prange=(0, lplot), plot_points=2000, thickness=3, color='green', display_tangent=True, scale=0.15, width_tangent=2, color_tangent='green', plot_points_tangent=20, horizon_color='lightgrey')
max lambda (plot): 55.0000000000000
graph = Li.plot(coordinates='xy', prange=(0, lplot), plot_points=500, thickness=3, color='green', display_tangent=True, scale=0.01, width_tangent=1, color_tangent='green', plot_points_tangent=20, horizon_color='lightgrey', axes_labels=[r'$x/m$', r'$y/m$']) graph.save("gik_spher_3d_r_39_xy.pdf") graph
Image in a Jupyter notebook

A polar spherical photon orbit

rph_pol(a) = 1 + 2*sqrt(1 - a^2/3)*cos(1/3*arccos((1 - a^2)/(1 - a^2/3)^(3/2))) rph_pol
a  213a2+1cos(13arccos(a21(13a2+1)32))+1\renewcommand{\Bold}[1]{\mathbf{#1}}a \ {\mapsto}\ 2 \, \sqrt{-\frac{1}{3} \, a^{2} + 1} \cos\left(\frac{1}{3} \, \arccos\left(-\frac{a^{2} - 1}{{\left(-\frac{1}{3} \, a^{2} + 1\right)}^{\frac{3}{2}}}\right)\right) + 1
r0 = rph_pol(a0) L = lsph(a0, r0) Q = qsph(a0, r0) r0, L, Q
(2.49269429554008,6.26333640524599×1016,22.8640201857508)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(2.49269429554008, -6.26333640524599 \times 10^{-16}, 22.8640201857508\right)
theta0(a0, L, Q)
0.000000000000000\renewcommand{\Bold}[1]{\mathbf{#1}}0.000000000000000
lmax = 30 P = M.point((0, r0, pi/2, 0), name='P') Li = M.geodesic([0, lmax], P, mu=0, E=E, L=0, Q=Q, a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=3.67971815257238t+(1.31343299672075×1024+2.14499886438313×108i)r+0.769552507817167θ+0.357746396090726ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 3.67971815257238 \frac{\partial}{\partial t } + \left( 1.31343299672075 \times 10^{-24} + 2.14499886438313 \times 10^{-8}i \right) \frac{\partial}{\partial r } + 0.769552507817167 \frac{\partial}{\partial {\theta} } + 0.357746396090726 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
v0 = Li.initial_tangent_vector() Li = M.geodesic([0, lmax], P, pt0=v0[0], pr0=0, pth0=v0[2], pph0=v0[3], a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=3.67971815257238t+0.769552507817167θ+0.357746396090726ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 3.67971815257238 \frac{\partial}{\partial t } + 0.769552507817167 \frac{\partial}{\partial {\theta} } + 0.357746396090726 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
Li.integrate(step=0.002, method='dopri5') #Li.check_integrals_of_motion(0.99*lmax)
/home/eric/sage/9.2/local/lib/python3.8/site-packages/scipy/integrate/_ode.py:1179: UserWarning: dopri5: step size becomes too small warnings.warn('{:s}: {:s}'.format(self.__class__.__name__,
lplot = 0.5*lmax print("max lambda (plot): ", lplot) Li.plot(prange=(0, lplot), plot_points=2000, thickness=3, color='green', display_tangent=True, scale=0.2, width_tangent=2, color_tangent='green', plot_points_tangent=20, horizon_color='lightgrey')
max lambda (plot): 15.0000000000000

Inner spherical orbits

To plot the inner orbits, and in particular orbits with r<0r<0, we use a map from Kerr spacetime to the Euclidean space based on the radial coordinate r^:=12(r+r2+4m2) \hat{r} := \frac{1}{2} \left( r + \sqrt{r^2 + 4m^2} \right) instead of the Boyer-Lindquist rr.

E4 = M.map_to_Euclidean().codomain() X4 = E4.cartesian_coordinates() t, x, y, z = X4[:] X4
(E4,(t,x,y,z))\renewcommand{\Bold}[1]{\mathbf{#1}}\left(\mathbb{E}^{4},(t, x, y, z)\right)
rhat = 1/2*(r + sqrt(r^2 + 4)) rhat
12r+12r2+4\renewcommand{\Bold}[1]{\mathbf{#1}}\frac{1}{2} \, r + \frac{1}{2} \, \sqrt{r^{2} + 4}
F = M.diff_map(E4, {(BL, X4): [t, rhat*sin(th)*cos(ph), rhat*sin(th)*sin(ph), rhat*cos(th)]}, name='F') F.display()
F:ME4(t,r,θ,ϕ)(t,x,y,z)=(t,12(r+r2+4)cos(ϕ)sin(θ),12(r+r2+4)sin(ϕ)sin(θ),12(r+r2+4)cos(θ))\renewcommand{\Bold}[1]{\mathbf{#1}}\begin{array}{llcl} F:& M & \longrightarrow & \mathbb{E}^{4} \\ & \left(t, r, {\theta}, {\phi}\right) & \longmapsto & \left(t, x, y, z\right) = \left(t, \frac{1}{2} \, {\left(r + \sqrt{r^{2} + 4}\right)} \cos\left({\phi}\right) \sin\left({\theta}\right), \frac{1}{2} \, {\left(r + \sqrt{r^{2} + 4}\right)} \sin\left({\phi}\right) \sin\left({\theta}\right), \frac{1}{2} \, {\left(r + \sqrt{r^{2} + 4}\right)} \cos\left({\theta}\right)\right) \end{array}

Marginally stable spherical photon orbit

r0 = 1 - (1 - a0^2)^(1/3) r0
0.539741795874205\renewcommand{\Bold}[1]{\mathbf{#1}}0.539741795874205
L = lsph(a0, r0) Q = qsph(a0, r0) L, Q
(1.53893384905757,0.282109845505914)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(1.53893384905757, 0.282109845505914\right)
theta0(a0, L, Q)
1.17336440458345\renewcommand{\Bold}[1]{\mathbf{#1}}1.17336440458345

Since all orbits with 0<r0rph0< r_0 \leq r_{\rm ph}^* (such as the marginally stable spherical orbit) have E<0E<0, we set E = -1 and L = -L:

lmax = 50 P = M.point((0, r0, pi/2, 0), name='P') Li = M.geodesic([0, lmax], P, mu=0, E=-1, L=-L, Q=Q, a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=7.69077392677338t+(3.13205131833926×1024+5.11502797462896×108i)r+1.82321137638829θ+5.62672311935440ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 7.69077392677338 \frac{\partial}{\partial t } + \left( 3.13205131833926 \times 10^{-24} + 5.11502797462896 \times 10^{-8}i \right) \frac{\partial}{\partial r } + 1.82321137638829 \frac{\partial}{\partial {\theta} } + 5.62672311935440 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
v0 = Li.initial_tangent_vector() Li = M.geodesic([0, lmax], P, pt0=v0[0], pr0=0, pth0=v0[2], pph0=v0[3], a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=7.69077392677338t+1.82321137638829θ+5.62672311935440ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 7.69077392677338 \frac{\partial}{\partial t } + 1.82321137638829 \frac{\partial}{\partial {\theta} } + 5.62672311935440 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
Li.integrate(step=0.001, method='dopri5') Li.check_integrals_of_motion(0.999*lmax)
quantity value initial value diff. relative diff.
print("Final point: ") show(BL[:], "=", BL(Li(0.999*lmax)))
Final point:
(t,r,θ,ϕ)=(302.91453819062644,0.5397417961010423,1.5090634888129522,210.47540919172215)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(t, r, {\theta}, {\phi}\right) \verb|=| \left(302.91453819062644, 0.5397417961010423, 1.5090634888129522, 210.47540919172215\right)

Plot with respect to r^\hat{r} coordinate:

sing_ring = circle((0,0,0), 1, thickness=3, color='orangered') r_minf = sphere((0,0,0), 0.03, color='black') \ + text3d("r=\u2212\u221E", (0,0,0.07), fontfamily='serif', fontstyle='italic', fontsize=20)
lplot = 0.06*lmax print("max lambda (plot): ", lplot) graph = Li.plot_integrated(chart=X4, mapping=F, ambient_coords=(x,y,z), prange=(0, lplot), thickness=3, plot_points=2000, color='green', display_tangent=True, scale=0.012, width_tangent=1, color_tangent='green', plot_points_tangent=20, label_axes=False) graph += sing_ring + r_minf \ + line([(0,0,-0.53), (0,0,0.53)], color='black', thickness=2) graph._extra_kwds['axes_labels'] = ['\u0302x', '\u0302y', '\u0302z'] graph
max lambda (plot): 3.00000000000000
lplot = 0.4*lmax print("max lambda (plot): ", lplot) graph = Li.plot_integrated(chart=X4, mapping=F, ambient_coords=(x,y,z), prange=(0, lplot), thickness=3, plot_points=2000, color='green', display_tangent=True, scale=0.012, width_tangent=1, color_tangent='green', plot_points_tangent=20, label_axes=False) graph += sing_ring + r_minf \ + line([(0,0,-0.53), (0,0,0.53)], color='black', thickness=2) graph._extra_kwds['axes_labels'] = ['\u0302x', '\u0302y', '\u0302z'] graph
max lambda (plot): 20.0000000000000

Stable inner spherical photon orbit at r0=0.5mr_0 = 0.5 m

r0 = 0.5 L = lsph(a0, r0) Q = qsph(a0, r0) L, Q
(1.53421052631579,0.268698060941828)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(1.53421052631579, 0.268698060941828\right)
theta0(a0, L, Q)
1.17991588772518\renewcommand{\Bold}[1]{\mathbf{#1}}1.17991588772518
lmax = 30 P = M.point((0, r0, pi/2, 0), name='P') Li = M.geodesic([0, lmax], P, mu=0, E=-1, L=-L, Q=Q, a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=7.00000000000000t+2.07344374774655θ+5.26315789473685ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 7.00000000000000 \frac{\partial}{\partial t } + 2.07344374774655 \frac{\partial}{\partial {\theta} } + 5.26315789473685 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
v0 = Li.initial_tangent_vector() Li = M.geodesic([0, lmax], P, pt0=v0[0], pr0=0, pth0=v0[2], pph0=v0[3], a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=7.00000000000000t+2.07344374774655θ+5.26315789473685ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 7.00000000000000 \frac{\partial}{\partial t } + 2.07344374774655 \frac{\partial}{\partial {\theta} } + 5.26315789473685 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
Li.integrate(step=0.001, method='dopri5') Li.check_integrals_of_motion(0.999*lmax)
quantity value initial value diff. relative diff.
print("Final point: ") show(BL[:], "=", BL(Li(0.999*lmax)))
Final point:
(t,r,θ,ϕ)=(160.26568413055006,0.499999999999837,1.4610686498265664,113.33060855013213)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(t, r, {\theta}, {\phi}\right) \verb|=| \left(160.26568413055006, 0.499999999999837, 1.4610686498265664, 113.33060855013213\right)

Plot in (Cartesian) Boyer-Lindquist coordinates:

Li.plot(prange=(0, lmax), plot_points=2000, thickness=3, color='green', display_tangent=True, scale=0.01, width_tangent=1, color_tangent='green', plot_points_tangent=20, plot_horizon=False)

Plot with respect to r^\hat{r} coordinate:

lplot = 0.25*lmax print("max lambda (plot): ", lplot) graph1 = Li.plot_integrated(chart=X4, mapping=F, ambient_coords=(x,y,z), prange=(0, lplot), thickness=3, plot_points=2000, color='green', display_tangent=True, scale=0.015, width_tangent=1, color_tangent='green', plot_points_tangent=20, label_axes=False) graph1 += sing_ring + r_minf graph1._extra_kwds['axes_labels'] = ['\u0302x', '\u0302y', '\u0302z'] graph1
max lambda (plot): 7.50000000000000

Vortical circular photon orbit at r0=rphr_0 = r_{\rm ph}^{**}

rph_ss = n(1/2 + cos(2/3*asin(a0) + 2*pi/3)) rph_ss
0.477673658836338\renewcommand{\Bold}[1]{\mathbf{#1}}-0.477673658836338
L = lsph(a0, rph_ss) Q = qsph(a0, rph_ss) L, Q
(0.229456449433387,0.519183008263141)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(-0.229456449433387, -0.519183008263141\right)
th0 = theta0(a0, L, Q) th1 = theta1(a0, L, Q) th0, th1
(0.513765577758655,0.513765602376411)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(0.513765577758655, 0.513765602376411\right)
th_ss = arcsin(sqrt(abs(L)/a0)) th_ss
0.513765590067533\renewcommand{\Bold}[1]{\mathbf{#1}}0.513765590067533
rh_ss = rhat.subs({r: rph_ss}) rh_ss
0.789289150745023\renewcommand{\Bold}[1]{\mathbf{#1}}0.789289150745023
lmax = 10 P = M.point((0, rph_ss, th_ss, 0), name='P') Li = M.geodesic([0, lmax], P, mu=0, E=E, L=L, Q=Q, a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=0.323260590036169t+(1.63266670244580×108)r+(1.99960017051231×108)θ1.40881021577044ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 0.323260590036169 \frac{\partial}{\partial t } + \left( 1.63266670244580 \times 10^{-8} \right) \frac{\partial}{\partial r } + \left( 1.99960017051231 \times 10^{-8} \right) \frac{\partial}{\partial {\theta} } -1.40881021577044 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
v0 = Li.initial_tangent_vector() Li = M.geodesic([0, lmax], P, pt0=v0[0], pr0=0, pth0=0, pph0=v0[3], a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=0.323260590036169t1.40881021577044ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 0.323260590036169 \frac{\partial}{\partial t } -1.40881021577044 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
Li.integrate(step=0.001, method='dopri5') Li.check_integrals_of_motion(0.999*lmax)
quantity value initial value diff. relative diff.
show("Final point: ", BL[:], "=", BL(Li(0.999*lmax)))
Finalxpoint:(t,r,θ,ϕ)=(3.229373294461296,0.47767365883633794,0.513765590067533,14.074014055546579)\renewcommand{\Bold}[1]{\mathbf{#1}}\verb|Final|\phantom{\verb!x!}\verb|point:| \left(t, r, {\theta}, {\phi}\right) \verb|=| \left(3.229373294461296, -0.47767365883633794, 0.513765590067533, -14.074014055546579\right)
lplot = 0.444*lmax print("max lambda (plot): ", lplot) vort_circ = Li.plot_integrated(chart=X4, mapping=F, ambient_coords=(x,y,z), prange=(0, lplot), thickness=3, plot_points=2000, color='lightgreen', display_tangent=True, scale=0.1, width_tangent=1, color_tangent='lightgreen', plot_points_tangent=5, label_axes=False) graph = vort_circ + sing_ring + r_minf \ + line([(0,0,0), (0,0,1.3*rh_ss)], color='black', thickness=2) graph._extra_kwds['axes_labels'] = ['\u0302x', '\u0302y', '\u0302z'] graph
max lambda (plot): 4.44000000000000

Vortical inner spherical photon orbit at r0=0.46mr_0 = -0.46 m

r0 = -0.46 L = lsph(a0, r0) Q = qsph(a0, r0) L, Q
(0.176485940879596,0.461285155596124)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(-0.176485940879596, -0.461285155596124\right)
th0 = theta0(a0, L, Q) th1 = theta1(a0, L, Q) th0, th1
(0.281889824619659,0.731306339672501)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(0.281889824619659, 0.731306339672501\right)
lmax = 20 P = M.point((0, r0, (th0+th1)/2, 0), name='P') Li = M.geodesic([0, lmax], P, mu=0, E=E, L=L, Q=Q, a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=0.357024161116205t+(1.84776601065215×108)r+0.396167049160545θ1.22114489356954ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 0.357024161116205 \frac{\partial}{\partial t } + \left( 1.84776601065215 \times 10^{-8} \right) \frac{\partial}{\partial r } + 0.396167049160545 \frac{\partial}{\partial {\theta} } -1.22114489356954 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
v0 = Li.initial_tangent_vector() Li = M.geodesic([0, lmax], P, pt0=v0[0], pr0=0, pth0=v0[2], pph0=v0[3], a_num=a0, name='Li', latex_name=r'\mathcal{L}', verbose=True)
Initial tangent vector:
p=0.357024161116205t+0.396167049160545θ1.22114489356954ϕ\renewcommand{\Bold}[1]{\mathbf{#1}}p = 0.357024161116205 \frac{\partial}{\partial t } + 0.396167049160545 \frac{\partial}{\partial {\theta} } -1.22114489356954 \frac{\partial}{\partial {\phi} }
The curve was correctly set. Parameters appearing in the differential system defining the curve are [a].
Li.integrate(step=0.001, method='dopri5') Li.check_integrals_of_motion(0.999*lmax)
quantity value initial value diff. relative diff.
print("Final point: ") show(BL[:], "=", BL(Li(0.999*lmax)))
Final point:
(t,r,θ,ϕ)=(6.6100475583006695,0.45999868463861343,0.39359482789056505,28.895385729902912)\renewcommand{\Bold}[1]{\mathbf{#1}}\left(t, r, {\theta}, {\phi}\right) \verb|=| \left(6.6100475583006695, -0.45999868463861343, 0.39359482789056505, -28.895385729902912\right)
lplot = lmax print("max lambda (plot): ", lplot) graph = Li.plot_integrated(chart=X4, mapping=F, ambient_coords=(x,y,z), prange=(0, lplot), thickness=3, plot_points=2000, color='green', display_tangent=True, scale=0.1, width_tangent=1, color_tangent='green', plot_points_tangent=20, label_axes=False)
max lambda (plot): 20
graph += sing_ring + r_minf + vort_circ \ + line([(0,0,0), (0,0,0.9)], color='black', thickness=2) graph._extra_kwds['axes_labels'] = ['\u0302x', '\u0302y', '\u0302z'] graph
graph + graph1