Visualizing the horizons and ergosurfaces of Kerr spacetime

This Jupyter notebook illustrates some applications of SageMath functionalities in general relativity, specifically in deriving and displaying the horizons and ergosurfaces of the Kerr spacetime. Most of the involved tools are part of the SageManifolds project.

Rogerio T. Cavalcanti

It requires the SageMath version at least equal to 9.2.

In [1]:
version()
Out[1]:
'SageMath version 9.4, Release Date: 2021-08-22'
In [2]:
%display latex
In [3]:
Parallelism().set(nproc=8)

Kerr spacetime in Boyer–Lindquist coordinates

In [4]:
a = var('a', domain='positive')
M.<t, r, th, ph> = manifolds.Kerr(m=1, a=a, coordinates='BL')
BL = M.default_chart()
In [5]:
g = M.metric()
g.display_comp()
Out[5]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\begin{array}{lcl} g_{ \, t \, t }^{ \phantom{\, t}\phantom{\, t} } & = & \frac{2 \, r}{a^{2} \cos\left({\theta}\right)^{2} + r^{2}} - 1 \\ g_{ \, t \, {\phi} }^{ \phantom{\, t}\phantom{\, {\phi}} } & = & \frac{2 \, a r \sin\left({\theta}\right)^{2}}{a^{2} \cos\left({\theta}\right)^{2} + r^{2}} \\ g_{ \, r \, r }^{ \phantom{\, r}\phantom{\, r} } & = & \frac{a^{2} \cos\left({\theta}\right)^{2} + r^{2}}{a^{2} + r^{2} - 2 \, r} \\ g_{ \, {\theta} \, {\theta} }^{ \phantom{\, {\theta}}\phantom{\, {\theta}} } & = & a^{2} \cos\left({\theta}\right)^{2} + r^{2} \\ g_{ \, {\phi} \, t }^{ \phantom{\, {\phi}}\phantom{\, t} } & = & \frac{2 \, a r \sin\left({\theta}\right)^{2}}{a^{2} \cos\left({\theta}\right)^{2} + r^{2}} \\ g_{ \, {\phi} \, {\phi} }^{ \phantom{\, {\phi}}\phantom{\, {\phi}} } & = & {\left(\frac{2 \, a^{2} r \sin\left({\theta}\right)^{2}}{a^{2} \cos\left({\theta}\right)^{2} + r^{2}} + a^{2} + r^{2}\right)} \sin\left({\theta}\right)^{2} \end{array}\]

Metric singularities and ergosurfaces

  • The $g_{tt},g_{t\phi}$ and $g_{\phi\phi}$ components are singular at the singular ring $a^2\cos^2\theta +r^2=0$, that is $r=0$ and $\theta =\frac{\pi}{2}$. It corresponds to a physical singularity, as checked below.
In [6]:
singular_ring = {r:0, th:pi/2}
  • Singular surfaces on $\displaystyle ({g_{rr}})^{-1} = 0$ (Horizons)
In [7]:
horizons = solve(1/g[1,1].expr()==0,r,solution_dict=True)
horizons
Out[7]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\left[\left\{r : -\sqrt{-a^{2} + 1} + 1\right\}, \left\{r : \sqrt{-a^{2} + 1} + 1\right\}\right]\]
In [8]:
inner_horizon, outer_horizon = horizons
  • The Ergosurfaces are the regions of vanishing $K_\mu K^\mu$, where $K = \frac{\partial}{\partial t }$ is a Killing vector field.
In [9]:
K = M.vector_field(1,0,0,0, name='K')
K.display()
Out[9]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}K = \frac{\partial}{\partial t }\]

Checking if $K$ is a Killing vector field $(\mathcal{L}_{_K}g = 0)$

In [10]:
g.lie_derivative(K) == 0
Out[10]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\mathrm{True}\]
In [11]:
g(K,K).display()
Out[11]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\begin{array}{llcl} g\left(K,K\right):& M & \longrightarrow & \mathbb{R} \\ & \left(t, r, {\theta}, {\phi}\right) & \longmapsto & \frac{2 \, r}{a^{2} \cos\left({\theta}\right)^{2} + r^{2}} - 1 \end{array}\]
In [12]:
ergosurfaces = solve(g(K,K).expr(),r,solution_dict=True)
ergosurfaces
Out[12]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\left[\left\{r : -\sqrt{-a^{2} \cos\left({\theta}\right)^{2} + 1} + 1\right\}, \left\{r : \sqrt{-a^{2} \cos\left({\theta}\right)^{2} + 1} + 1\right\}\right]\]
In [13]:
inner_ergo, outer_ergo = ergosurfaces

List of surfaces

In [14]:
surfaces_param = [outer_ergo,outer_horizon,inner_horizon,inner_ergo,singular_ring]

Rational polynomial coordinates

In rational polinomial coordinates all components of the Kerr metric are rational polynomials, which in principle make it easyer to handle. We are going to use such coordinates for checking the Kretschmann scalar over the horizon and ergosurfaces of the spacetime.

In [15]:
RP.<t, r, ch, ph> = M.chart(r't:(-oo,+oo) r:(0,+oo) ch:(-1,1):\chi ph:(-pi,pi):periodic:\phi')

Transition map from Boyer–Lindquist coordinates to rational polynomial coordinates and its inverse.

In [16]:
BL_to_RP = BL.transition_map(RP, [t, r, cos(th), ph])
BL_to_RP.display()
Out[16]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\left\{\begin{array}{lcl} t & = & t \\ r & = & r \\ {\chi} & = & \cos\left({\theta}\right) \\ {\phi} & = & {\phi} \end{array}\right.\]
In [17]:
BL_to_RP.set_inverse(t, r, acos(ch), ph)
BL_to_RP.inverse().display()
Out[17]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\left\{\begin{array}{lcl} t & = & t \\ r & = & r \\ {\theta} & = & \arccos\left({\chi}\right) \\ {\phi} & = & {\phi} \end{array}\right.\]
In [18]:
g.display_comp(RP.frame(),RP)
Out[18]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\begin{array}{lcl} g_{ \, t \, t }^{ \phantom{\, t}\phantom{\, t} } & = & -\frac{a^{2} {\chi}^{2} + r^{2} - 2 \, r}{a^{2} {\chi}^{2} + r^{2}} \\ g_{ \, t \, {\phi} }^{ \phantom{\, t}\phantom{\, {\phi}} } & = & -\frac{2 \, {\left(a {\chi}^{2} - a\right)} r}{a^{2} {\chi}^{2} + r^{2}} \\ g_{ \, r \, r }^{ \phantom{\, r}\phantom{\, r} } & = & \frac{a^{2} {\chi}^{2} + r^{2}}{a^{2} + r^{2} - 2 \, r} \\ g_{ \, {\chi} \, {\chi} }^{ \phantom{\, {\chi}}\phantom{\, {\chi}} } & = & -\frac{a^{2} {\chi}^{2} + r^{2}}{{\chi}^{2} - 1} \\ g_{ \, {\phi} \, t }^{ \phantom{\, {\phi}}\phantom{\, t} } & = & -\frac{2 \, {\left(a {\chi}^{2} - a\right)} r}{a^{2} {\chi}^{2} + r^{2}} \\ g_{ \, {\phi} \, {\phi} }^{ \phantom{\, {\phi}}\phantom{\, {\phi}} } & = & -\frac{a^{4} {\chi}^{4} - a^{4} {\chi}^{2} + {\left({\chi}^{2} - 1\right)} r^{4} + {\left(a^{2} {\chi}^{4} - a^{2}\right)} r^{2} - 2 \, {\left(a^{2} {\chi}^{4} - 2 \, a^{2} {\chi}^{2} + a^{2}\right)} r}{a^{2} {\chi}^{2} + r^{2}} \end{array}\]

Setting the default chart and frame

In [19]:
M.set_default_chart(RP)
In [20]:
M.set_default_frame(RP.frame())

Riemann tensor, Ricci tensor and Kretschmann scalar

In [21]:
%time Riem = g.riemann()
CPU times: user 5.26 s, sys: 634 ms, total: 5.89 s
Wall time: 36.6 s
In [22]:
%time Ric = g.ricci()
CPU times: user 4.43 s, sys: 65.2 ms, total: 4.49 s
Wall time: 2.6 s
In [23]:
Ric == 0
Out[23]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\mathrm{True}\]
In [24]:
%time R_up = Riem.up(g)
CPU times: user 1.54 s, sys: 236 ms, total: 1.78 s
Wall time: 21.2 s
In [25]:
%time R_down = Riem.down(g)
CPU times: user 404 ms, sys: 92.4 ms, total: 497 ms
Wall time: 3.52 s
In [26]:
%time Kretschmann_scalar = R_up['^{abcd}']*R_down['_{abcd}']
CPU times: user 49.8 s, sys: 891 ms, total: 50.7 s
Wall time: 31.7 s
In [27]:
Kretschmann_scalar.display()
Out[27]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\begin{array}{llcl} & M & \longrightarrow & \mathbb{R} \\ & \left(t, r, {\theta}, {\phi}\right) & \longmapsto & -\frac{48 \, {\left(a^{6} \cos\left({\theta}\right)^{6} - 15 \, a^{4} r^{2} \cos\left({\theta}\right)^{4} + 15 \, a^{2} r^{4} \cos\left({\theta}\right)^{2} - r^{6}\right)}}{a^{12} \cos\left({\theta}\right)^{12} + 6 \, a^{10} r^{2} \cos\left({\theta}\right)^{10} + 15 \, a^{8} r^{4} \cos\left({\theta}\right)^{8} + 20 \, a^{6} r^{6} \cos\left({\theta}\right)^{6} + 15 \, a^{4} r^{8} \cos\left({\theta}\right)^{4} + 6 \, a^{2} r^{10} \cos\left({\theta}\right)^{2} + r^{12}} \\ & \left(t, r, {\chi}, {\phi}\right) & \longmapsto & -\frac{48 \, {\left(a^{6} {\chi}^{6} - 15 \, a^{4} {\chi}^{4} r^{2} + 15 \, a^{2} {\chi}^{2} r^{4} - r^{6}\right)}}{a^{12} {\chi}^{12} + 6 \, a^{10} {\chi}^{10} r^{2} + 15 \, a^{8} {\chi}^{8} r^{4} + 20 \, a^{6} {\chi}^{6} r^{6} + 15 \, a^{4} {\chi}^{4} r^{8} + 6 \, a^{2} {\chi}^{2} r^{10} + r^{12}} \end{array}\]

Getting and factoring the symbolic expression in the default chart

In [28]:
K_scalar = Kretschmann_scalar.expr().factor()
K_scalar
Out[28]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}-\frac{48 \, {\left(a^{2} {\chi}^{2} + 4 \, a {\chi} r + r^{2}\right)} {\left(a^{2} {\chi}^{2} - 4 \, a {\chi} r + r^{2}\right)} {\left(a {\chi} + r\right)} {\left(a {\chi} - r\right)}}{{\left(a^{2} {\chi}^{2} + r^{2}\right)}^{6}}\]

Kretschmann scalar along the singular ring, horizons and ergosurfaces

Singular Ring $(r=0,\chi=0)$

In [29]:
K_scalar.subs(r=0)
Out[29]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}-\frac{48}{a^{6} {\chi}^{6}}\]
In [30]:
K_scalar.subs(ch=0)
Out[30]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\frac{48}{r^{6}}\]

Outer ergosurface, outer horizon and inner horizon at $\chi = 0$

In [31]:
for k in ['outer_ergo','outer_horizon','inner_horizon']:
    print(k)
    display(K_scalar.subs(eval(k)).subs({cos(th):ch}).subs(ch=0))
outer_ergo
\[\newcommand{\Bold}[1]{\mathbf{#1}}\frac{3}{4}\]
outer_horizon
\[\newcommand{\Bold}[1]{\mathbf{#1}}\frac{48}{{\left(\sqrt{-a^{2} + 1} + 1\right)}^{6}}\]
inner_horizon
\[\newcommand{\Bold}[1]{\mathbf{#1}}\frac{48}{{\left(\sqrt{-a^{2} + 1} - 1\right)}^{6}}\]

Inner ergosurface for $\chi \neq 0$ (the inner ergosurface coincides with the singular ring at $\chi = 0$)

In [32]:
K_inner_ergo = K_scalar.subs(inner_ergo).subs({cos(th):ch}).canonicalize_radical()
K_inner_ergo
Out[32]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\frac{6 \, {\left(4 \, a^{6} {\chi}^{6} - 21 \, a^{4} {\chi}^{4} + 21 \, a^{2} {\chi}^{2} + {\left(12 \, a^{4} {\chi}^{4} - 19 \, a^{2} {\chi}^{2} + 4\right)} \sqrt{a {\chi} + 1} \sqrt{-a {\chi} + 1} - 4\right)}}{a^{6} {\chi}^{6} - 18 \, a^{4} {\chi}^{4} + 48 \, a^{2} {\chi}^{2} + 2 \, {\left(3 \, a^{4} {\chi}^{4} - 16 \, a^{2} {\chi}^{2} + 16\right)} \sqrt{a {\chi} + 1} \sqrt{-a {\chi} + 1} - 32}\]

Series expansion up to $O(\chi^5)$

In [33]:
K_inner_ergo.series(ch,5)
Out[33]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}{(-\frac{48}{a^{6}})} {\chi}^{(-6)} + {(\frac{252}{a^{4}})} {\chi}^{(-4)} + {(-\frac{252}{a^{2}})} {\chi}^{(-2)} + \frac{189}{4} + {(\frac{45}{16} \, a^{2})} {\chi}^{2} + {(\frac{45}{64} \, a^{4})} {\chi}^{4} + \mathcal{O}\left({\chi}^{5}\right)\]

Setting the default chart and frame back to Boyer–Lindquist

In [34]:
M.set_default_chart(BL)
M.set_default_frame(BL.frame())

Kerr coordinates

The Kerr original coordinates will be used as an intermediate step for introducing the Kerr-Schild coordinates.

In [35]:
Kr.<u, r, th, vph> = M.chart(r'u:(-oo,+oo) r:(0,+oo) th:(0,pi):\theta vph:(-pi,pi):periodic:\varphi')
In [36]:
f(r) = r/(a^2+r^2-2*r)
assume(a<1)
F(r) = integral(f(r),r)
In [37]:
Kr_to_BL = Kr.transition_map(BL, [u-2*F(r), r, th, vph-a*F(r)])
Kr_to_BL.display()
Out[37]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\left\{\begin{array}{lcl} t & = & u - \frac{\log\left(\frac{r - \sqrt{-a^{2} + 1} - 1}{r + \sqrt{-a^{2} + 1} - 1}\right)}{\sqrt{-a^{2} + 1}} - \log\left(a^{2} + r^{2} - 2 \, r\right) \\ r & = & r \\ {\theta} & = & {\theta} \\ {\phi} & = & -\frac{1}{2} \, a {\left(\frac{\log\left(\frac{r - \sqrt{-a^{2} + 1} - 1}{r + \sqrt{-a^{2} + 1} - 1}\right)}{\sqrt{-a^{2} + 1}} + \log\left(a^{2} + r^{2} - 2 \, r\right)\right)} + {\varphi} \end{array}\right.\]
In [38]:
Kr_to_BL.inverse().display()
Out[38]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\left\{\begin{array}{lcl} u & = & \frac{{\left(a^{2} - 1\right)} t + {\left(a^{2} - 1\right)} \log\left(a^{2} + r^{2} - 2 \, r\right) + \sqrt{a + 1} \sqrt{-a + 1} \log\left(-\frac{a^{2} + r^{2} - 2 \, r}{a^{2} + 2 \, \sqrt{a + 1} \sqrt{-a + 1} {\left(r - 1\right)} - r^{2} + 2 \, r - 2}\right)}{a^{2} - 1} \\ r & = & r \\ {\theta} & = & {\theta} \\ {\varphi} & = & \frac{\sqrt{a + 1} a \sqrt{-a + 1} \log\left(-\frac{a^{2} + r^{2} - 2 \, r}{a^{2} + 2 \, \sqrt{a + 1} \sqrt{-a + 1} {\left(r - 1\right)} - r^{2} + 2 \, r - 2}\right) + 2 \, {\left(a^{2} - 1\right)} {\phi} + {\left(a^{3} - a\right)} \log\left(a^{2} + r^{2} - 2 \, r\right)}{2 \, {\left(a^{2} - 1\right)}} \end{array}\right.\]

Showing the change of frame from BL to Kerr

In [39]:
M.change_of_frame(BL.frame(),Kr.frame())[:]
Out[39]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\left(\begin{array}{rrrr} 1 & -\frac{2 \, r}{a^{2} + r^{2} - 2 \, r} & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & -\frac{a r}{a^{2} + r^{2} - 2 \, r} & 0 & 1 \end{array}\right)\]

Surfaces in Kerr-Schild coordinates

In [40]:
KS.<u,x,y,z> = M.chart()

Change of coordinates from Kerr to Kerr-Schild

In [41]:
Kr_to_KS = Kr.transition_map(KS, [u, (r*cos(vph) - a*sin(vph))*sin(th),
                                (r*sin(vph) + a*cos(vph))*sin(th),
                                r*cos(th)])
Kr_to_KS.display()
Out[41]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\left\{\begin{array}{lcl} u & = & u \\ x & = & {\left(r \cos\left({\varphi}\right) - a \sin\left({\varphi}\right)\right)} \sin\left({\theta}\right) \\ y & = & {\left(a \cos\left({\varphi}\right) + r \sin\left({\varphi}\right)\right)} \sin\left({\theta}\right) \\ z & = & r \cos\left({\theta}\right) \end{array}\right.\]

Parametrization of the surfaces in Kerr-Schild coordinates

In [42]:
surfaces_KS = [vector([s.subs(param) for s in Kr_to_KS(u, r, th, ph)[1:]]) for param in surfaces_param]

Plotting

In [43]:
# plotting data
surfs_data = {
'outer_ergo': {'name': 'Outer ergosurface',
               'color': 'gray',
               'z_label': 1,
               'param_index': 0,
               'phi1': 7*pi/5,
               'plot_points_factor': 1},
'outer_orizon': {'name': 'Outer horizon', 
                 'color': colormaps.Set1(1)[:3], 
                 'z_label': .5,
                 'param_index': 1, 
                 'phi1': 7*pi/5, 
                 'plot_points_factor': 1},
'inner_horizon': {'name': 'Inner horizon', 
                  'color': colormaps.Set1(4)[:3], 
                  'z_label': 0,
                  'param_index': 2, 
                  'phi1': 6*pi/5, 
                  'plot_points_factor': .7},
'inner_ergo': {'name': 'Inner ergosurface',
               'color': colormaps.Set1(3)[:3],
               'z_label': -0.5,
               'param_index': 3,
               'phi1': 2*pi,
               'plot_points_factor': .7}}

Python function for plotting the surfaces

In [44]:
def kerr_surfaces(surf, a=.99, print_labels=True, plot_points=30, mesh=True, **kwargs):
    if a >1 or a < 0:
        print("choose 'a' between 0 and 1")
        return None
#     Labels
    if print_labels:
        Ker_BH = text3d('Kerr black hole', (-2,-5,2.5), fontsize='200%', fontfamily='serif', fontweight='bold')
        sep_line = text3d(r'___', (-2,-5,1.7), fontsize='160%', fontfamily='serif', fontweight='bold')
        a_label = text3d('a = ' + str(a.n(digits=5)), (-2,-5,2), fontsize='170%')
        s_ring_label = text3d('Singular ring', (-2,-5,-1), color='red', fontsize='170%', fontfamily='serif')
        labels = sum([text3d(S['name'],
                             (-2,-5,S['z_label']),
                             color=S['color'],
                             fontsize='170%', 
                             fontfamily='serif') for S in surfs_data.values()])
        labels += Ker_BH + a_label + s_ring_label + sep_line
    else: labels = Graphics()
#     Surfaces
    s_ring = parametric_plot3d(surf[4].subs(a=a),(ph,0,2*pi), color='red', thickness=4)
    plots = sum([parametric_plot3d(surf[S['param_index']].subs(a=a),
                                   (th,0,pi),
                                   (ph,0,S['phi1']), 
                                   color=S['color'], 
                                   mesh=mesh,
                                   plot_points=S['plot_points_factor']*plot_points, 
                                   frame=False, 
                                   **kwargs) for S in surfs_data.values()])
    plots += s_ring
    return plots+labels

In [45]:
kerr_surfaces(surfaces_KS, 0.999, viewpoint=[[-0.6557,-0.5284,-0.5394],112.41])
Out[45]:

Dark theme

In [46]:
kerr_surfaces(surfaces_KS, .9, viewpoint=[[-0.6557,-0.5284,-0.5394],112.41], theme='dark')
Out[46]:

Immersion in Euclidean space

We can also see the surfaces immersed in the Euclidian space $\mathbb{E}^3$.

In [47]:
E.<x,y,z> = EuclideanSpace(3)
spherical.<r, th, ph> = E.spherical_coordinates()

Differential map from Kerr coordinates to the Euclidean space

In [48]:
Kr_to_E = M.diff_map(E, {(Kr, spherical): [r,th,ph]}, 
                     name='Kr_to_E', 
                     latex_name=r'\Phi_{_{\text{Kerr} \to \mathbb{E}^3}}')
In [49]:
Kr_to_E.display()
Out[49]:
\[\newcommand{\Bold}[1]{\mathbf{#1}}\begin{array}{llcl} \Phi_{_{\text{Kerr} \to \mathbb{E}^3}}:& M & \longrightarrow & \mathbb{E}^{3} \\ & \left(t, r, {\theta}, {\phi}\right) & \longmapsto & \left(x, y, z\right) = \left(r \cos\left({\phi}\right) \sin\left({\theta}\right), r \sin\left({\phi}\right) \sin\left({\theta}\right), r \cos\left({\theta}\right)\right) \\ & \left(t, r, {\theta}, {\phi}\right) & \longmapsto & \left(r, {\theta}, {\phi}\right) = \left(r, \arctan\left(r \sin\left({\theta}\right), r \cos\left({\theta}\right)\right), \arctan\left(r \sin\left({\phi}\right) \sin\left({\theta}\right), r \cos\left({\phi}\right) \sin\left({\theta}\right)\right)\right) \\ & \left(t, r, {\chi}, {\phi}\right) & \longmapsto & \left(x, y, z\right) = \left(\sqrt{{\chi} + 1} \sqrt{-{\chi} + 1} r \cos\left({\phi}\right), \sqrt{{\chi} + 1} \sqrt{-{\chi} + 1} r \sin\left({\phi}\right), {\chi} r\right) \\ & \left(t, r, {\chi}, {\phi}\right) & \longmapsto & \left(r, {\theta}, {\phi}\right) = \left(r, \arctan\left(\sqrt{{\chi} + 1} \sqrt{-{\chi} + 1} r, {\chi} r\right), \arctan\left(\sqrt{{\chi} + 1} \sqrt{-{\chi} + 1} r \sin\left({\phi}\right), \sqrt{{\chi} + 1} \sqrt{-{\chi} + 1} r \cos\left({\phi}\right)\right)\right) \\ & \left(u, r, {\theta}, {\varphi}\right) & \longmapsto & \left(x, y, z\right) = \left(r \cos\left({\phi}\right) \sin\left({\theta}\right), r \sin\left({\phi}\right) \sin\left({\theta}\right), r \cos\left({\theta}\right)\right) \\ & \left(u, r, {\theta}, {\varphi}\right) & \longmapsto & \left(r, {\theta}, {\phi}\right) = \left(r, {\theta}, {\phi}\right) \end{array}\]

Coordinates in Euclidean space

In [50]:
coordinates = Kr_to_E(M.point((u,r,th,vph), chart=Kr)).coordinates()

Surfaces in Euclidean space

In [51]:
surfaces_E = [vector([s.subs(param) for s in coordinates]) for param in surfaces_param]
In [52]:
kerr_surfaces(surfaces_E, .96, viewpoint=[[-0.8499,-0.3478,-0.396],91.88])
Out[52]: