| Hosted by CoCalc | Download
Kernel: SageMath 6.10

Conformal completion of Minkowski spacetime

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

These computations are based on SageManifolds (v0.9)

The worksheet file (ipynb format) can be downloaded from here.

First we set up the notebook to display mathematical objects using LaTeX formatting:

%display latex

Spherical coordinates on Minkowski spacetime

We declare the spacetime manifold MM:

M = Manifold(4, 'M') print M
4-dimensional differentiable manifold M

and the spherical coordinates (t,r,θ,ϕ)(t,r,\theta,\phi) as a chart on MM:

XS.<t,r,th,ph> = M.chart(r't r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi') XS
XS.coord_range()

In term of these coordinates, the Minkowski metric is

g = M.lorentzian_metric('g') g[0,0] = -1 g[1,1] = 1 g[2,2] = r^2 g[3,3] = r^2*sin(th)^2 g.display()

Null coordinates

Let us introduce the null coordinates u=tru=t-r (retarded time) and v=t+rv=t+r (advanced time):

XN.<u,v,th,ph> = M.chart(r'u v th:(0,pi):\theta ph:(0,2*pi):\phi') XN.add_restrictions(v-u>0) XN
XN.coord_range()
XS_to_XN = XS.transition_map(XN, [t-r, t+r, th, ph]) XS_to_XN.display()
XS_to_XN.inverse().display()

In terms of the null coordinates (u,v,θ,ϕ)(u,v,\theta,\phi), the Minkowski metric writes

g.display(XN.frame(), XN)

Let us plot the coordinate grid (u,v)(u,v) in terms of the coordinates (t,r)(t,r):

graph = XN.plot(XS, ambient_coords=(r,t), fixed_coords={th: pi/2, ph: pi}, nb_values=17, plot_points=200, color='green', style={u: '-', v: ':'}, thickness={u: 1, v: 2}) show(graph)
Image in a Jupyter notebook
show(graph, xmin=0, xmax=4, ymin=0, ymax=4, aspect_ratio=1, fontsize=16)
Image in a Jupyter notebook
graph.save("glo_null_coord.pdf", xmin=0, xmax=4, ymin=0, ymax=4, aspect_ratio=1, fontsize=16)

Compactified null coordinates

Instead of (u,v)(u,v), which span R\mathbb{R}, let consider the coordinates U=atanuU = \mathrm{atan}\, u and V=atanvV = \mathrm{atan}\, v, which span (π2,π2)\left(-\frac{\pi}{2}, \frac{\pi}{2}\right):

graph = plot(atan(u), (u,-6, 6), thickness=2, axes_labels=[r'$u$', r'$U$']) + \ line([(-6,-pi/2), (6,-pi/2)], linestyle='--') + \ line([(-6,pi/2), (6,pi/2)], linestyle='--') show(graph, aspect_ratio=1)
Image in a Jupyter notebook
graph.save('glo_atan.pdf', aspect_ratio=1)
XNC.<U,V,th,ph> = M.chart(r'U:(-pi/2,pi/2) V:(-pi/2,pi/2) th:(0,pi):\theta ph:(0,2*pi):\phi') XNC.add_restrictions(V-U>0) XNC
XNC.coord_range()
XN_to_XNC = XN.transition_map(XNC, [atan(u), atan(v), th, ph]) XN_to_XNC.display()
XN_to_XNC.inverse().display()

Expressed in terms of the coordinates (U,V,θ,ϕ)(U,V,\theta,\phi), the metric tensor is

g.display(XNC.frame(), XNC)

Let us call Ω2\Omega^{-2} the common factor:

Omega = M.scalar_field({XNC: 2*cos(U)*cos(V)}, name='Omega', latex_name=r'\Omega') Omega.display()
Omega.display(XS)

Conformal metric

We introduce the metric g~=Ω2g\tilde g = \Omega^2 g:

gt = M.lorentzian_metric('gt', latex_name=r'\tilde{g}') gt.set(Omega^2*g) gt.display(XNC.frame(), XNC)

Clearly the metric components g~θθ{\tilde g}_{\theta\theta} and g~ϕϕ{\tilde g}_{\phi\phi} can be simplified further. Let us do it by hand, by extracting the symbolic expression via expr():

g22 = gt[XNC.frame(), 2, 2, XNC].expr() g22
g22.factor().reduce_trig()
g33st = gt[XNC.frame(), 3, 3, XNC].expr() / sin(th)^2 g33st
g33st.factor().reduce_trig()
gt.add_comp(XNC.frame())[2,2, XNC] = g22.factor().reduce_trig() gt.add_comp(XNC.frame())[3,3, XNC] = g33st.factor().reduce_trig() * sin(th)^2

Hence the final form of the conformal metric in terms of the compactified null coordinates:

gt.display(XNC.frame(), XNC)

In terms of the non-compactified null coordinates (u,v,θ,ϕ)(u,v,\theta,\phi):

gt.display(XN.frame(), XN)

and in terms of the default coordinates (t,r,θ,ϕ)(t,r,\theta,\phi):

gt.display()

Einstein cylinder coordinates

Let us introduce some coordinates (τ,χ)(\tau,\chi) such that the null coordinates (U,V)(U,V) are respectively half the retarded time τχ\tau -\chi and half the advanced time τ+χ\tau+\chi:

XC.<tau,ch,th,ph> = M.chart(r'tau:(-pi,pi):\tau ch:(0,pi):\chi th:(0,pi):\theta ph:(0,2*pi):\phi') XC.add_restrictions([tau<pi-ch, tau>ch-pi]) XC
XC.coord_range()
XC_to_XNC = XC.transition_map(XNC, [(tau-ch)/2, (tau+ch)/2, th, ph]) XC_to_XNC.display()
XC_to_XNC.inverse().display()

The conformal metric takes then the form of the standard metric on the Einstein cylinder R×S3\mathbb{R}\times\mathbb{S}^3:

gt.display(XC.frame(), XC)

The square of the conformal factor expressed in all the coordinates introduced so far:

(Omega^2).display()
XS_to_XC = M.coord_change(XNC,XC) * M.coord_change(XN, XNC) * M.coord_change(XS, XN) XS_to_XC.display()
XC_to_XS = M.coord_change(XN, XS) * M.coord_change(XNC, XN) * M.coord_change(XC,XNC) XC_to_XS.display()

The expressions for tt and rr can be simplified:

tc = XC_to_XS(tau,ch,th,ph)[0] tc
tc.reduce_trig()
rc = XC_to_XS(tau,ch,th,ph)[1] rc
rc.reduce_trig()
XS_to_XC.set_inverse(tc.reduce_trig(), rc.reduce_trig(), th, ph) XC_to_XS = XS_to_XC.inverse()
Check of the inverse coordinate transformation: t == t r == r th == th ph == ph tau == arctan((sin(ch) + sin(tau))/(cos(ch) + cos(tau))) + arctan(-(sin(ch) - sin(tau))/(cos(ch) + cos(tau))) ch == arctan((sin(ch) + sin(tau))/(cos(ch) + cos(tau))) - arctan(-(sin(ch) - sin(tau))/(cos(ch) + cos(tau))) th == th ph == ph
XC_to_XS.display()

Conformal Penrose diagram

Let us draw the coordinate grid (t,r)(t,r) in terms of the coordinates (τ,χ)(\tau,\chi):

graphXS = XS.plot(XC, ambient_coords=(ch, tau), fixed_coords={th: pi/2, ph: pi}, max_range=30, nb_values=51, plot_points=250, color={t: 'red', r: 'grey'}) graph_i0 = circle((pi,0), 0.05, fill=True, color='grey') + \ text(r"$i^0$", (3.3, 0.2), fontsize=18, color='grey') graph_ip = circle((0,pi), 0.05, fill=True, color='red') + \ text(r"$i^+$", (0.25, 3.3), fontsize=18, color='red') graph_im = circle((0,-pi), 0.05, fill=True, color='red') + \ text(r"$i^-$", (0.25, -3.3), fontsize=18, color='red') graph_Ip = line([(0,pi), (pi,0)], color='green', thickness=2) + \ text(r"$\mathscr{I}^+$", (1.8, 1.8), fontsize=18, color='green') graph_Im = line([(0,-pi), (pi,0)], color='green', thickness=2) + \ text(r"$\mathscr{I}^-$", (1.8, -1.8), fontsize=18, color='green') graph = graphXS + graph_i0 + graph_ip + graph_im + graph_Ip + graph_Im show(graph)
Image in a Jupyter notebook
graph.save('glo_conf_diag_Mink.pdf')

Some blow-up near i0i^0:

graph = XS.plot(XC, ambient_coords=(ch, tau), fixed_coords={th: pi/2, ph: pi}, max_range=100, nb_values=41, plot_points=200, color={t: 'red', r: 'grey'}) graph += circle((pi,0), 0.005, fill=True, color='grey') + \ text(r"$i^0$", (pi, 0.02), fontsize=18, color='grey') show(graph, xmin=3., xmax=3.2, ymin=-0.2, ymax=0.2, aspect_ratio=1)
Image in a Jupyter notebook

To produce a more satisfactory figure, let us use some logarithmic radial coordinate:

XL.<t, rh, th, ph> = M.chart(r't rh:\rho th:(0,pi):\theta ph:(0,2*pi):\phi') XL
XS_to_XL = XS.transition_map(XL, [t, ln(r), th, ph]) XS_to_XL.display()
XS_to_XL.inverse().display()
XL_to_XC = M.coord_change(XS, XC) * M.coord_change(XL, XS) XC_to_XL = M.coord_change(XS, XL) * M.coord_change(XC, XS)
graph = XL.plot(XC, ambient_coords=(ch, tau), fixed_coords={th: pi/2, ph: pi}, ranges={t: (-20, 20), rh: (-2, 10)}, nb_values=19, color={t: 'red', rh: 'grey'}) graph += circle((pi,0), 0.005, fill=True, color='grey') + \ text(r"$i^0$", (pi, 0.02), fontsize=18, color='grey') show(graph, xmin=3., xmax=3.2, ymin=-0.2, ymax=0.2, aspect_ratio=1)
Image in a Jupyter notebook

Null radial geodesics in the conformal diagram

To get a view of the null radial geodesics in the conformal diagram, it suffices to plot the chart (u,v,θ,ϕ)(u,v,\theta,\phi) in terms of the chart (τ,χ,θ,ϕ)(\tau,\chi,\theta,\phi). The following plot shows

  • the null geodesics defined by (u,θ,ϕ)=(u0,π/2,π)(u,\theta,\phi) = (u_0, \pi/2,\pi) for 17 values of u0u_0 evenly spaced in [8,8][-8,8] (dashed lines)

  • the null geodesics defined by (v,θ,ϕ)=(v0,π/2,π)(v,\theta,\phi) = (v_0, \pi/2,\pi) for 17 values of v0v_0 evenly spaced in [8,8][-8,8] (solid lines)

graphXN = XN.plot(XC, ambient_coords=(ch, tau), fixed_coords={th: pi/2, ph: pi}, nb_values=17, plot_points=150, color='green', style={u: '-', v: ':'}, thickness={u: 1, v: 2}) graph = graphXN + graph_i0 + graph_ip + graph_im + graph_Ip + graph_Im show(graph)
Image in a Jupyter notebook
graph.save('glo_conf_Mink_null.pdf')

Conformal factor

The conformal factor expressed in various coordinate systems:

Omega.display()

The expression in terms of (τ,χ,θ,ϕ)(\tau,\chi,\theta,\phi) can be simplified:

Omega.expr(XC)
s = Omega.expr(XC) - cos(tau) - cos(ch) s.trig_reduce()

Hence we set

Omega.add_expr(cos(tau) + cos(ch), XC) Omega.display()

A plot of Ω\Omega in terms of the coordinates (τ,χ)(\tau,\chi):

graph = plot3d(Omega.expr(XC), (tau,-pi,pi), (ch,0,pi), adaptive=True) + \ plot3d(0, (tau,-pi,pi), (ch,0,pi), color='yellow', opacity=0.7) graph = set_axes_labels(graph, 'tau', 'chi', '') show(graph, aspect_ratio=1)
show(graph, aspect_ratio=1, viewer='tachyon')
Image in a Jupyter notebook

Differential of the conformal factor

The 1-form dΩ\mathrm{d}\Omega is:

dOmega = Omega.differential() print dOmega
1-form dOmega on the 4-dimensional differentiable manifold M
dOmega.display()
dOmega.display(XNC.frame(), XNC)
M.set_default_chart(XNC) M.set_default_frame(XNC.frame())
dOmega.display()
dOmega1 = M.one_form() dOmega1[0] = -2*cos(V)*sin(U) dOmega1[1] = -2*cos(U)*sin(V) dOmega1.display()
dOmega1.display(XC.frame(), XC)

Einstein static universe

E = Manifold(4, 'E') print E
4-dimensional differentiable manifold E
XE.<tau,ch,th,ph> = E.chart(r'tau:\tau ch:(0,pi):\chi th:(0,pi):\theta ph:(0,2*pi):\phi') XE
XE.coord_range()
XC.coord_range()

Embedding of MM in EE

Phi = M.diff_map(E, {(XC, XE): [tau, ch, th, ph]}, name='Phi', latex_name=r'\Phi') print Phi ; Phi.display()
Differentiable map Phi from the 4-dimensional differentiable manifold M to the 4-dimensional differentiable manifold E
XS.plot(XE, mapping=Phi, ambient_coords=(ch, tau), fixed_coords={th: pi/2, ph: pi}, plot_points=200, color={t: 'red', r: 'grey'})
Image in a Jupyter notebook

Embedding of EE in R5\mathbb{R}^5

R5 = Manifold(5, 'R^5', latex_name=r'\mathbb{R}^5') print R5
5-dimensional differentiable manifold R^5
X5.<tau,W,X,Y,Z> = R5.chart(r'tau:\tau W X Y Z') X5
Psi = E.diff_map(R5, {(XE, X5): [tau, cos(ch), sin(ch)*sin(th)*cos(ph), sin(ch)*sin(th)*sin(ph), sin(ch)*cos(th)]}, name='Psi', latex_name=r'\Psi') print Psi ; Psi.display()
Differentiable map Psi from the 4-dimensional differentiable manifold E to the 5-dimensional differentiable manifold R^5

The Einstein cylinder:

graphE = XE.plot(X5, ambient_coords=(W,X,tau), mapping=Psi, fixed_coords={th:pi/2, ph:0.001}, max_range=4, nb_values=9, color='silver', thickness=0.5, label_axes=False) # phi = 0 graphE += XE.plot(X5, ambient_coords=(W,X,tau), mapping=Psi, fixed_coords={th:pi/2, ph:pi}, max_range=4, nb_values=9, color='silver', thickness=0.5) # phi = pi show(graphE)

Embedding of MM in R5\mathbb{R}^5

The embedding Θ:MR5\Theta:\, M\rightarrow \mathbb{R}^5 is obtained by composition of the embeddings Φ:ME\Phi:\, M\rightarrow E and Ψ:ER5\Psi:\, E\rightarrow \mathbb{R}^5:

Theta = Psi * Phi print Theta Theta.display()
Differentiable map from the 4-dimensional differentiable manifold M to the 5-dimensional differentiable manifold R^5
graphM = XS.plot(X5, ambient_coords=(W,X,tau), mapping=Theta, fixed_coords={th:pi/2, ph:0.001}, max_range=30, nb_values=51, plot_points=250, color={t:'red', r:'black'}, label_axes=False) # phi = 0 graphM += XS.plot(X5, ambient_coords=(W,X,tau), mapping=Theta, fixed_coords={th:pi/2, ph:pi}, max_range=30, nb_values=51, plot_points=250, color={t:'red', r:'black'}, label_axes=False) # phi = pi show(graphE+graphM, aspect_ratio=1)
graph = (graphE+graphM).rotate((0,0,1), 0.2) show(graph, aspect_ratio=(2,2,1), viewer='tachyon', frame=False, figsize=20)
Image in a Jupyter notebook
graph = (graphE+graphM).rotate((0,0,1), pi) show(graph, aspect_ratio=(2,2,1), viewer='tachyon', frame=False, figsize=20)
Image in a Jupyter notebook
graphMN = XN.plot(X5, ambient_coords=(W,X,tau), mapping=Theta, fixed_coords={th:pi/2, ph:0.001}, max_range=16, nb_values=21, plot_points=150, color='green', style={u: '-', v: ':'}, label_axes=False) # phi = 0 graphMN += XN.plot(X5, ambient_coords=(W,X,tau), mapping=Theta, fixed_coords={th:pi/2, ph:pi}, max_range=16, nb_values=21, plot_points=150, color='green', style={u: '-', v: ':'}, label_axes=False) # phi = pi
show(graphE+graphMN, aspect_ratio=1, frame=False)
show(graphE+graphMN, aspect_ratio=(2,2,1), viewer='tachyon', frame=False, figsize=20)
Image in a Jupyter notebook