This notebook demonstrates a few capabilities of SageMath in computations regarding the Simon-Mars tensor. The corresponding tools have been developed within the SageManifolds project (version 1.3, as included in SageMath 8.3).
Click here to download the notebook 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 8.2 is required to run this notebook:
version()
First we set up the notebook to display mathematical objects using LaTeX rendering:
%display latex
Since some computations are quite long, we ask for running them in parallel on 8 cores:
Parallelism().set(nproc=8)
We declare the Kerr spacetime (or more precisely the part of the Kerr spacetime covered by Boyer-Lindquist coordinates) as a 4-dimensional Lorentzian manifold $\mathcal{M}$:
M = Manifold(4, 'M', latex_name=r'\mathcal{M}',
structure='Lorentzian')
print(M)
The standard Boyer-Lindquist coordinates $(t,r,\theta,\phi)$ are introduced by declaring a chart $X$ on $\mathcal{M}$, 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:
X.<t,r,th,ph> = M.chart(r't r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
print(X) ; X
The 2 parameters $m$ and $a$ of the Kerr spacetime are declared as symbolic variables:
var('m, a', domain='real')
Let us set the components of the spacetime metric in the coordinate frame associated with Boyer-Lindquist coordinates, which is the current manifold's default frame:
g = M.metric()
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()
g[:]
The Levi-Civita connection $\nabla$ associated with $g$:
nabla = g.connection() ; print(nabla)
As a check, we 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 X.frame()
X.frame()
Let us consider the first vector field of this frame:
xi = X.frame()[0] ; xi
print(xi)
The 1-form associated to it by metric duality is
xi_form = xi.down(g)
xi_form.set_name('xi_form', r'\underline{\xi}')
print(xi_form) ; xi_form.display()
Its covariant derivative is
nab_xi = nabla(xi_form)
print(nab_xi) ; nab_xi.display()
Let us check that the Killing equation is satisfied:
nab_xi.symmetrize().display()
Equivalently, we check that the Lie derivative of the metric along $\xi$ vanishes:
g.lie_der(xi).display()
Thank to Killing equation, $\nabla_g \underline{\xi}$ is antisymmetric. We may therefore define a 2-form by $F := - \nabla_g \xi$. Here we enforce the antisymmetry by calling the function antisymmetrize() on nab_xi:
F = - nab_xi.antisymmetrize()
F.set_name('F')
print(F)
F.display()
We check that
F == - nab_xi
The squared norm of the Killing vector is:
lamb = - g(xi,xi)
lamb.set_name('lambda', r'\lambda')
print(lamb)
lamb.display()
Instead of invoking $g(\xi,\xi)$, we could have evaluated $\lambda$ by means of the 1-form $\underline{\xi}$ acting on the vector field $\xi$:
lamb == - xi_form(xi)
or, using index notation as $\lambda = - \xi_a \xi^a$:
lamb == - ( xi_form['_a']*xi['^a'] )
The Riemann curvature tensor associated with $g$ is
Riem = g.riemann()
print(Riem)
The component $R^0_{\ \, 123} = R^t_{\ \, r\theta\phi}$ is
Riem[0,1,2,3]
The Ricci tensor:
Ric = g.ricci()
print(Ric)
Let us check that the Kerr metric is a vacuum solution of Einstein equation, i.e. that the Ricci tensor vanishes identically:
Ric.display()
The Weyl conformal curvature tensor is
C = g.weyl()
print(C)
Let us exhibit two of its components $C^0_{\ \, 123}$ and $C^0_{\ \, 101}$:
C[0,1,2,3]
C[0,1,0,1]
To form the Simon-Mars tensor, we need the fully covariant (type-(0,4) tensor) form of the Weyl tensor (i.e. $C_{\alpha\beta\mu\nu} = g_{\alpha\sigma} C^\sigma_{\ \, \beta\mu\nu}$); we get it by lowering the first index with the metric:
Cd = C.down(g)
print(Cd)
The (monoterm) symmetries of this tensor are those inherited from the Weyl tensor, i.e. the antisymmetry on the last two indices (position 2 and 3, the first index being at position 0):
Cd.symmetries()
Actually, Cd is also antisymmetric with respect to the first two indices (positions 0 and 1), as we can check:
Cd == Cd.antisymmetrize(0,1)
To take this symmetry into account explicitely, we set
Cd = Cd.antisymmetrize(0,1)
Hence we have now
Cd.symmetries()
The Simon-Mars tensor with respect to the Killing vector $\xi$ is a rank-3 tensor introduced by Marc Mars in 1999 (Class. Quantum Grav. 16, 2507). It has the remarkable property to vanish identically if, and only if, the spacetime $(\mathcal{M},g)$ is locally isometric to a Kerr spacetime.
Let us evaluate the Simon-Mars tensor by following the formulas given in Mars' article. The starting point is the self-dual complex 2-form associated with the Killing 2-form $F$, i.e. the object $\mathcal{F} := F + i \, {}^* F$, where ${}^*F$ is the Hodge dual of $F$:
FF = F + I * F.hodge_dual(g)
FF.set_name('FF', r'\mathcal{F}') ; print(FF)
FF.display()
Let us check that $\mathcal{F}$ is self-dual, i.e. that it obeys ${}^* \mathcal{F} = -i \mathcal{F}$:
FF.hodge_dual(g) == - I * FF
Let us form the right self-dual of the Weyl tensor as follows $$\mathcal{C}_{\alpha\beta\mu\nu} = C_{\alpha\beta\mu\nu} + \frac{i}{2} \epsilon^{\rho\sigma}_{\ \ \ \mu\nu} \, C_{\alpha\beta\rho\sigma},$$ where $\epsilon^{\rho\sigma}_{\ \ \ \mu\nu}$ is associated to the Levi-Civita tensor $\epsilon_{\rho\sigma\mu\nu}$ and is obtained by
eps = g.volume_form(2) # 2 = the first 2 indices are contravariant
print(eps)
eps.symmetries()
The right self-dual Weyl tensor is then
CC = Cd + I/2*( eps['^rs_..']*Cd['_..rs'] )
CC.set_name('CC', r'\mathcal{C}') ; print(CC)
CC.symmetries()
CC[0,1,2,3]
The Ernst 1-form $\sigma_\alpha = 2 \mathcal{F}_{\mu\alpha} \, \xi^\mu$ (0 = contraction on the first index of $\mathcal{F}$):
sigma = 2*FF.contract(0, xi)
Instead of invoking the function contract(), we could have used the index notation to denote the contraction:
sigma == 2*( FF['_ma']*xi['^m'] )
sigma.set_name('sigma', r'\sigma') ; print(sigma)
sigma.display()
The symmetric bilinear form $\gamma = \lambda \, g + \underline{\xi}\otimes\underline{\xi}$:
gamma = lamb*g + xi_form * xi_form
gamma.set_name('gamma', r'\gamma') ; print(gamma)
gamma.display()
First we evaluate $$ S^{(1)}_{\alpha\beta\gamma} = 4 \mathcal{C}_{\mu\alpha\nu\beta} \, \xi^\mu \, \xi^\nu \, \sigma_\gamma $$
S1 = 4*( CC.contract(0,xi).contract(1,xi) ) * sigma
print(S1)
Then we form the tensor $$ S^{(2)}_{\alpha\beta\gamma} = - \gamma_{\alpha\beta} \, \mathcal{C}_{\rho\gamma\mu\nu} \, \xi^\rho \, \mathcal{F}^{\mu\nu} $$ by first computing $\mathcal{C}_{\rho\gamma\mu\nu} \, \xi^\rho$:
xiCC = CC['_.r..']*xi['^r']
print(xiCC)
We use the index notation to perform the double contraction $\mathcal{C}_{\gamma\rho\mu\nu} \mathcal{F}^{\mu\nu}$:
FFuu = FF.up(g)
S2 = gamma * ( xiCC['_.mn']*FFuu['^mn'] )
print(S2)
S2.symmetries()
The Simon-Mars tensor with respect to $\xi$ is obtained by antisymmetrizing $S^{(1)}$ and $S^{(2)}$ on their last two indices and adding them: $$ S_{\alpha\beta\gamma} = S^{(1)}_{\alpha[\beta\gamma]} + S^{(2)}_{\alpha[\beta\gamma]} $$ We use the index notation for the antisymmetrization:
S1A = S1['_a[bc]']
S2A = S2['_a[bc]']
An equivalent writing would have been (the last two indices being in position 1 and 2):
# S1A = S1.antisymmetrize(1,2)
# S2A = S2.antisymmetrize(1,2)
The Simon-Mars tensor is
S = S1A + S2A
S.set_name('S') ; print(S)
S.symmetries()
S.display()
We thus recover the fact that the Simon-Mars tensor vanishes identically in Kerr spacetime.
To check that the above computation was not trival, here is the component 112=$rr\theta$ for each of the two parts of the Simon-Mars tensor:
S1A[1,1,2]
S2A[1,1,2]
S1A[1,1,2] + S2A[1,1,2]