This worksheet demonstrates a few capabilities of SageMath in computations regarding Kerr spacetime. More precisely, it focuses of the Killing tensor $K$ found by Walker & Penrose [Commun. Math. Phys. 18, 265 (1970)]. The employed differential geometry tools have been developed within the SageManifolds project (version 1.1, as included in SageMath 8.1).
Click here to download the worksheet file (ipynb format). To run it, you must start SageMath within the Jupyter notebook, via the command sage -n jupyter
NB: a version of SageMath at least equal to 7.5 is required to run this worksheet:
version()
'SageMath version 8.1, Release Date: 2017-12-07'
First we set up the notebook to display mathematical objects using LaTeX rendering:
%display latex
We also define a viewer for 3D plots (use 'threejs'
or 'jmol'
for interactive 3D graphics):
viewer3D = 'threejs' # must be 'threejs', jmol', 'tachyon' or None (default)
To speed up the computations, we ask for running them in parallel on 8 cores:
Parallelism().set(nproc=8)
We declare the Kerr spacetime (or more precisely the Boyer-Lindquist domain of Kerr spacetime) as a 4-dimensional diffentiable manifold:
M = Manifold(4, 'M', r'\mathcal{M}')
print(M)
4-dimensional differentiable manifold M
Let us declare the Boyer-Lindquist coordinates via the method chart()
, the argument of which is a string expressing the coordinates names, their ranges (the default is $(-\infty,+\infty)$) and their LaTeX symbols:
BL.<t,r,th,ph> = M.chart(r't r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
print(BL) ; BL
Chart (M, (t, r, th, ph))
BL[0], BL[1]
The 2 parameters $m$ and $a$ of the Kerr spacetime are declared as symbolic variables:
var('m, a', domain='real')
Let us introduce the spacetime metric:
g = M.lorentzian_metric('g')
The metric is set by its components in the coordinate frame associated with Boyer-Lindquist coordinates, which is the current manifold's default frame:
rho2 = r^2 + (a*cos(th))^2
Delta = r^2 -2*m*r + a^2
g[0,0] = -(1-2*m*r/rho2)
g[0,3] = -2*a*m*r*sin(th)^2/rho2
g[1,1], g[2,2] = rho2/Delta, rho2
g[3,3] = (r^2+a^2+2*m*r*(a*sin(th))^2/rho2)*sin(th)^2
g.display()
A matrix view of the components with respect to the manifold's default vector frame:
g[:]
The list of the non-vanishing components:
g.display_comp()
The Levi-Civita connection $\nabla$ associated with $g$:
nabla = g.connection() ; print(nabla)
Levi-Civita connection nabla_g associated with the Lorentzian metric g on the 4-dimensional differentiable manifold M
Let us verify that the covariant derivative of $g$ with respect to $\nabla$ vanishes identically:
nabla(g).display()
The default vector frame on the spacetime manifold is the coordinate basis associated with Boyer-Lindquist coordinates:
M.default_frame() is BL.frame()
BL.frame()
Let us consider the first vector field of this frame:
xi = BL.frame()[0] ; xi
print(xi)
Vector field d/dt on the 4-dimensional differentiable manifold M
The 1-form associated to it by metric duality is
xi_form = xi.down(g) ; xi_form.display()
Its covariant derivative is
nab_xi = nabla(xi_form) ; print(nab_xi) ; nab_xi.display()
Tensor field of type (0,2) on the 4-dimensional differentiable manifold M
Let us check that the Killing equation is satisfied:
nab_xi.symmetrize() == 0
Similarly, let us check that $\frac{\partial}{\partial\phi}$ is a Killing vector:
chi = BL.frame()[3] ; chi
nabla(chi.down(g)).symmetrize() == 0
We introduce the principal null vectors $k$ and $\ell$ of Kerr spacetime:
k = M.vector_field(name='k')
k[:] = [(r^2+a^2)/(2*rho2), -Delta/(2*rho2), 0, a/(2*rho2)]
k.display()
el = M.vector_field(name='el', latex_name=r'\ell')
el[:] = [(r^2+a^2)/Delta, 1, 0, a/Delta]
el.display()
Let us check that $k$ and $\ell$ are null vectors:
g(k,k).expr()
g(el,el).expr()
Their scalar product is $-1$:
g(k,el).expr()
Let us evaluate the "acceleration" of $k$, i.e. $\nabla_k k$:
acc_k = nabla(k).contract(k)
acc_k.display()
We check that $k$ is a pregeodesic vector, i.e. that $\nabla_k k = \kappa_k k$ for some scalar field $\kappa_k$:
for i in [0,1,3]:
show(acc_k[i] / k[i])
kappa_k = acc_k[[0]] / k[[0]]
kappa_k.display()
acc_k == kappa_k * k
Similarly let us evaluate the "acceleration" of $\ell$:
acc_l = nabla(el).contract(el)
acc_l.display()
Hence $\ell$ is a geodesic vector.
We need the 1-forms associated to $k$ and $\ell$ by metric duality:
uk = k.down(g)
ul = el.down(g)
The Walker-Penrose Killing tensor $K$ is then formed as $$ K = \rho^2 (\underline{\ell}\otimes \underline{k} + (\underline{k}\otimes \underline{\ell}) + r^2 g $$
K = rho2*(ul*uk+ uk*ul) + r^2*g
K.set_name('K')
print(K)
Tensor field K of type (0,2) on the 4-dimensional differentiable manifold M
K.display_comp()
DK = nabla(K)
print(DK)
Tensor field nabla_g(K) of type (0,3) on the 4-dimensional differentiable manifold M
DK.display_comp()
Let us check that $K$ is a Killing tensor:
DK.symmetrize().display()
Equivalently, we may write, using index notation:
DK['_(abc)'].display()