#!/usr/bin/env python # coding: utf-8 # # Anti-de Sitter spacetime # # This worksheet demonstrates a few capabilities of SageMath in computations regarding the 4-dimensional anti-de Sitter spacetime. The corresponding tools have been developed within the [SageManifolds](http://sagemanifolds.obspm.fr) project (version 1.2, as included in SageMath 8.2). # # Click [here](https://raw.githubusercontent.com/sagemanifolds/SageManifolds/master/Worksheets/v1.2/SM_AdS.ipynb) 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 8.2 is required to run this worksheet: # In[1]: version() # First we set up the notebook to display mathematical objects using LaTeX rendering: # In[2]: get_ipython().run_line_magic('display', 'latex') # We also define a viewer for 3D plots (use `'threejs'` or `'jmol'` for interactive 3D graphics): # In[3]: viewer3D = 'threejs' # must be 'threejs', 'jmol', 'tachyon' or None (default) # ## Spacetime manifold # # We declare the anti-de Sitter spacetime as a 4-dimensional Lorentzian manifold: # In[4]: M = Manifold(4, 'M', r'\mathcal{M}', structure='Lorentzian') print(M); M #

We consider hyperbolic coordinates $(\tau,\rho,\theta,\phi)$ on $\mathcal{M}$. Allowing for the standard coordinate singularities at $\rho=0$, $\theta=0$ or $\theta=\pi$, these coordinates cover the entire spacetime manifold (which is topologically $\mathbb{R}^4$). If we restrict ourselves to regular coordinates (i.e. to considering only mathematically well defined charts), the hyperbolic coordinates cover only an open part of $\mathcal{M}$, which we call $\mathcal{M}_0$, on which $\rho$ spans the open interval $(0,+\infty)$, $\theta$ the open interval $(0,\pi)$ and $\phi$ the open interval $(0,2\pi)$. Therefore, we declare:

# In[5]: M0 = M.open_subset('M_0', r'\mathcal{M}_0' ) X_hyp. = M0.chart(r'ta:\tau rh:(0,+oo):\rho th:(0,pi):\theta ph:(0,2*pi):\phi') print(X_hyp) ; X_hyp # In[6]: X_hyp.coord_range() # ## $\mathbb{R}^{2,3}$ as an ambient space # The AdS metric can be defined as that induced by the immersion of $\mathcal{M}$ in $\mathbb{R}^{2,3}$, the latter being nothing but $\mathbb{R}^5$ equipped with a flat pseudo-Riemannian metric of signature $(-,-,+,+,+)$. Let us construct $\mathbb{R}^{2,3}$ as a 5-dimensional manifold covered by canonical coordinates: # In[7]: R23 = Manifold(5, 'R23', r'\mathbb{R}^{2,3}', structure='pseudo-Riemannian', signature=1, metric_name='h') X23. = R23.chart() print(X23); X23 # We define the pseudo-Riemannian metric of $\mathbb{R}^{2,3}$: # In[8]: h = R23.metric() h[0,0], h[1,1], h[2,2], h[3,3], h[4,4] = -1, -1, 1, 1, 1 h.display() # The AdS immersion into $\mathbb{R}^{2,3}$ is defined as a differential map $\Phi$ from $\mathcal{M}$ to $\mathbb{R}^{2,3}$, by providing its expression in terms of $\mathcal{M}$'s default chart (which is X_hyp = $(\mathcal{M}_0,(\tau,\rho,\theta,\phi))$ ) and $\mathbb{R}^{2,3}$'s default chart (which is X23 = $(\mathbb{R}^{2,3},(U,V,X,Y,Z))$ ): # In[9]: var('l', latex_name=r'\ell', domain='real') assume(l>0) Phi = M.diff_map(R23, [l*cosh(rh)*cos(ta/l), l*cosh(rh)*sin(ta/l), l*sinh(rh)*sin(th)*cos(ph), l*sinh(rh)*sin(th)*sin(ph), l*sinh(rh)*cos(th)], name='Phi', latex_name=r'\Phi') print(Phi); Phi.display() # The constant $\ell$ is the AdS length parameter. Considering AdS metric as a solution of vacuum Einstein equation with negative cosmological constant $\Lambda$, one has $\ell = \sqrt{-3/\Lambda}$. # # Let us evaluate the image of a point via the map $\Phi$: # In[10]: p = M((ta, rh, th, ph), name='p'); print(p) # The coordinates of $p$ in the chart `X_hyp`: # In[11]: X_hyp(p) # In[12]: q = Phi(p); print(q) # In[13]: X23(q) # The image of $\mathcal{M}$ by the immersion $\Phi$ is a hyperboloid of one sheet, of equation $$-U^2-V^2+X^2+Y^2+Z^2=-\ell^2.$$ # Indeed: # In[14]: (Uq,Vq,Xq,Yq,Zq) = X23(q) s = - Uq^2 - Vq^2 + Xq^2 + Yq^2 + Zq^2 s.simplify_full() # We may use the immersion $\Phi$ to draw the coordinate grid $(\tau,\rho)$ in terms of the coordinates $(U,V,X)$ for $\theta=\pi/2$ and $\phi=0$ ($X\geq 0$ part) or $\phi=\pi$ # ($X\leq 0$ part). The red (rep. grey) curves are those for which $\rho={\rm const}$ # (resp. $\tau={\rm const}$): # In[15]: graph_hyp = X_hyp.plot(X23, mapping=Phi, ambient_coords=(V,X,U), fixed_coords={th:pi/2, ph:0}, ranges={ta:(0,2*pi), rh:(0,2)}, number_values=9, color={ta:'red', rh:'grey'}, thickness=2, parameters={l:1}, label_axes=False) # phi = 0 => X > 0 part graph_hyp += X_hyp.plot(X23, mapping=Phi, ambient_coords=(V,X,U), fixed_coords={th:pi/2, ph:pi}, ranges={ta:(0,2*pi), rh:(0,2)}, number_values=9, color={ta:'red', rh:'grey'}, thickness=2, parameters={l:1}, label_axes=False) # phi = pi => X < 0 part show(graph_hyp, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['V','X','U']) # To have a nicer picture, we add the plot of the hyperboloid obtained by `parametric_plot` with $(\tau,\rho)$ as parameters and the expressions of $(U,V,X)$ in terms of $(\tau,\rho)$ deduced from the coordinate representation of $\Phi$: # In[16]: Phi.coord_functions() # the default pair of charts (X_hyp, X23) is assumed # In[17]: Ug = Phi.coord_functions()[0](ta,rh,pi/2,0).subs({l:1}) # l=1 substituted to have numerical values Vg = Phi.coord_functions()[1](ta,rh,pi/2,0).subs({l:1}) Xg = Phi.coord_functions()[2](ta,rh,pi/2,0).subs({l:1}) Ug, Vg, Xg # In[18]: hyperboloid = parametric_plot3d([Vg, Xg, Ug], (ta,0,2*pi), (rh,-2,2), color=(1.,1.,0.9)) graph_hyp += hyperboloid show(graph_hyp, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['V','X','U']) # ## Spacetime metric # As mentionned above, the AdS metric $g$ on $\mathcal{M}$ is that induced by the flat metric $h$ on $\mathbb{R}^{2,3}$, i.e.$g$ is the pullback of $h$ by the differentiable map $\Phi$: # In[19]: g = M.metric() g.set( Phi.pullback(h) ) #

The expression of $g$ in terms of $\mathcal{M}$'s default frame is found to be

# In[20]: g.display() # In[21]: g[:] #

Curvature

#

The Riemann tensor of $g$ is

# In[22]: Riem = g.riemann() print(Riem) # In[23]: Riem.display_comp(only_nonredundant=True) #

The Ricci tensor:

# In[24]: Ric = g.ricci() print(Ric) Ric.display() # In[25]: Ric[:] #

The Ricci scalar:

# In[26]: R = g.ricci_scalar() print(R) R.display() # We recover the fact that AdS spacetime has a constant curvature. It is indeed a **maximally symmetric space**. In particular, the Riemann tensor is expressible as # $$ R^i_{\ \, jlk} = \frac{R}{n(n-1)} \left( \delta^i_{\ \, k} g_{jl} - \delta^i_{\ \, l} g_{jk} \right), $$ # where $n$ is the dimension of $\mathcal{M}$: $n=4$ in the present case. Let us check this formula here, under the form $R^i_{\ \, jlk} = -\frac{R}{6} g_{j[k} \delta^i_{\ \, l]}$: # In[27]: delta = M.tangent_identity_field() Riem == - (R/6)*(g*delta).antisymmetrize(2,3) # 2,3 = last positions of the type-(1,3) tensor g*delta # We may also check that AdS metric is a solution of the vacuum **Einstein equation** with (negative) cosmological constant $\Lambda = - 3/\ell^2$: # In[28]: Lambda = -3/l^2 Ric - 1/2*R*g + Lambda*g == 0 # ## Radial null geodesics # # Null geodesics that are radial with respect to coordinates $(\tau,\rho,\theta,\phi)$ obey # $$ \tau = \pm 2 \ell \left( \mathrm{atan} \left(\mathrm{e}^\rho\right) - \frac{\pi}{4} \right) + \tau_0,$$ # where $\tau_0$ is a constant (the value of $\tau$ at $\rho=0$). Note that, due to the homogeneity of AdS spacetime, any null geodesic is a "radial" geodesic with respect to some coordinate system $(\tau',\rho',\theta',\phi')$, as in Minkowski spacetime, any null geodesic is a straight line and one can always find a Minkowskian coordinate system $(t',x',y',z')$ with respect to which the null geodesic is radial. # # Let us consider two finite families of radial null geodesics having $\theta=\pi/2$ and $\phi=0$ or $\pi$: # - `null_geod1` has $\phi=\pi$ when $\tau< 0$ and $\phi=0$ when $\tau>0$ # - `null_geod2` has $\phi=0$ when $\tau<0$ and $\phi=\pi$ when $\tau>0$ # In[29]: lamb = var('lamb', latex_name=r'\lambda') null_geod1 = [M.curve({X_hyp: [2*sgn(lamb)*l*(atan(exp(abs(lamb))) - pi/4) + 2*pi*(i-4)/8, abs(lamb), pi/2, pi*unit_step(-lamb)]}, (lamb, -oo, +oo)) for i in range(9)] null_geod2 = [M.curve({X_hyp: [2*sgn(lamb)*l*(atan(exp(abs(lamb))) - pi/4) + 2*pi*(i-4)/8, abs(lamb), pi/2, pi*unit_step(lamb)]}, (lamb, -oo, +oo)) for i in range(9)] null_geods = null_geod1 + null_geod2 # In[30]: print(null_geods[0]) # In[31]: null_geods[0].display() # In[32]: null_geods[9].display() # To graphically display these geodesics, we introduce a Cartesian-like coordinate system # $(\tau,x_\rho,y_\rho,z_\rho)$ linked to $(\tau,\rho,\theta,\phi)$ by the standard formulas: # In[33]: X_hyp_graph. = M0.chart(r'ta:\tau x_rho:x_\rho y_rho:y_\rho z_rho:z_\rho') hyp_to_hyp_graph = X_hyp.transition_map(X_hyp_graph, [ta, rh*sin(th)*cos(ph), rh*sin(th)*sin(ph), rh*cos(th)]) hyp_to_hyp_graph.display() # Let us plot the null geodesics in terms of the coordinates $(\tau,x_\rho)$: # In[34]: graph_2d = Graphics() for geod in null_geods: geod.expr(geod.domain().canonical_chart(), X_hyp_graph) graph_2d += geod.plot(X_hyp_graph, ambient_coords=(x_rho,ta), prange=(-4,4), parameters={l:1}, color='green', thickness=1.5) graph_2d += X_hyp_graph.plot(X_hyp_graph, ambient_coords=(x_rho,ta), fixed_coords={th:0, ph:pi}, ranges={ta:(-pi,pi), x_rho:(-4,4)}, number_values={ta: 9, x_rho: 9}, color={ta:'red', x_rho:'grey'}, parameters={l:1}) show(graph_2d, aspect_ratio=1, ymin=-pi, ymax=pi) # We can also get a 3D view of the radial null geodesics via the isometric immersion $\Phi$: # In[35]: graph_3d = Graphics() for geod in null_geods: graph_3d += geod.plot(X23, mapping=Phi, ambient_coords=(V,X,U), prange=(-2,2), parameters={l:1}, color='green', thickness=2, plot_points=20, label_axes=False) show(graph_3d+graph_hyp, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['V','X','U']) # We notice that the image by $\Phi$ of the null geodesics are straight lines of $\mathbb{R}^{2,3}$. # This is not surprising since $\Phi$ is an isometric immersion and the null geodesics of # $\mathbb{R}^{2,3}$ are straight lines. Note that the two considered families of null geodesics of $\mathrm{AdS}_4$ # rule the hyperboloid (remember that a hyperboloid of one sheet is a ruled surface). # ## A timelike geodesic # # Let us consider a timelike geodesic: # In[36]: time_geod = M.curve({X_hyp: [ta, abs(atanh(4*sin(ta/l)/5)), pi/2, pi*unit_step(frac(ta/(2*pi*l))-1/2)]}, (ta, -oo, +oo)) time_geod.display() # and draw it in terms of the $(\tau,x_\rho)$ coordinates: # In[37]: graph = time_geod.plot(X_hyp_graph, ambient_coords=(x_rho,ta), plot_points=800, parameters={l:1}, color='purple', thickness=2) show(graph+graph_2d, aspect_ratio=1, ymin=-pi, ymax=pi) # Let us superpose the timelike geodesic to the 3D plot obtained via the immersion $\Phi$ of AdS$_4$ in $\mathbb{R}^{2,3}$: # In[38]: graph_3d += time_geod.plot(X23, mapping=Phi, ambient_coords=(V,X,U), prange=(0,2*pi), parameters={l:1}, color='purple', thickness=2, label_axes=False) show(graph_3d+graph_hyp, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['V','X','U']) # We notice that the immersed timelike geodesic looks like an ellipse. It is actually a *circle* of $\mathbb{R}^{2,3}$, as we can see by considering its restriction to $\tau\in(0,\pi)$ (this avoids absolute values and step functions and therefore ease the simplifications): # In[39]: time_geod_partial = M.curve({X_hyp: [ta, atanh(4*sin(ta/l)/5), pi/2, 0]}, (ta, 0, pi)) time_geod_partial.display() # The immersed curve: # In[40]: (Phi*time_geod_partial).display() # The position vector with respect to the origin of $\mathbb{R}^{2,3}$: # In[41]: v = R23.vector_field(name='v') v[:] = (Phi*time_geod_partial).expr() v.display() # In[42]: h(v,v).display() # Since $v$ has a constant (negative) squared norm, we conclude that the immersed timelike geodesic is a "circle" of $\mathbb{R}^{2,3}$. This circle is nothing but the intersection of the hyperboloid with a 2-plane through the origin. Note also that the straight line representing the immersed null geodesics are also intersections of the hyperboloid with some 2-planes through the origin, but with a different inclination. # ## "Static" coordinates # Let us introduce coordinates $(\tau,R,\theta,\phi)$ on the AdS spacetime via the simple coordinate change # $$R = \ell \sinh(\rho) $$ # Despite the $(\tau,\rho,\theta,\phi)$ coordinates are as adapted to the spacetime staticity as the $(\tau,R,\theta,\phi)$ coordinates, the latter ones are usually called "static" coordinates. # In[43]: X_stat. = M0.chart(r'ta:\tau R:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi') print(X_stat); X_stat # In[44]: X_stat.coord_range() # In[45]: hyp_to_stat = X_hyp.transition_map(X_stat, [ta, l*sinh(rh), th, ph]) hyp_to_stat.display() # In[46]: hyp_to_stat.set_inverse(ta, asinh(R/l), th, ph, verbose=True) stat_to_hyp = hyp_to_stat.inverse() stat_to_hyp.display() # The expression of the metric tensor in the new coordinates is # In[47]: g.display(X_stat.frame(), X_stat) # Similarly, the expression of the Riemann tensor is # In[48]: Riem.display_comp(X_stat.frame(), X_stat, only_nonredundant=True) # In[49]: Phi.display(X_stat, X23) # A view of the various geodesics in terms of the coordinates $(\tau,R)$: # In[50]: graph = Graphics() for geod in null_geods: geod.expr(geod.domain().canonical_chart(), X_stat) graph += geod.plot(X_stat, ambient_coords=(R,ta), prange=(-3,3), parameters={l:1}, color='green', thickness=1.5) graph += X_stat.plot(X_stat, ambient_coords=(R,ta), fixed_coords={th:0, ph:pi}, ranges={ta:(-pi,pi), R:(0,5)}, number_values={ta: 9, R: 11}, color={ta:'grey', R:'grey'}, parameters={l:1}) time_geod.expr(time_geod.domain().canonical_chart(), X_stat) graph += time_geod.plot(X_stat, ambient_coords=(R,ta), plot_points=800, parameters={l:1}, color='purple', thickness=2) show(graph, aspect_ratio=1, ymin=-pi, ymax=pi, xmin=0, xmax=5) # ## Conformal coordinates # # We introduce coordinates $(\tilde{\tau},\chi,\theta,\phi)$ such that # $$ \tilde{\tau} = \frac{\tau}{\ell} \qquad\mbox{and}\qquad \chi = \mathrm{atan}\left(\frac{R}{\ell}\right) $$ # In[51]: X_conf. = M0.chart(r'tat:\tilde{\tau} ch:(0,pi/2):\chi th:(0,pi):\theta ph:(0,2*pi):\phi') print(X_conf); X_conf # In[52]: X_conf.coord_range() # In[53]: stat_to_conf = X_stat.transition_map(X_conf, [ta/l, atan(R/l), th, ph]) stat_to_conf.display() # In[54]: stat_to_conf.inverse().display() # In[55]: hyp_to_conf = stat_to_conf * hyp_to_stat hyp_to_conf.display() # In[56]: conf_to_hyp = hyp_to_stat.inverse() * stat_to_conf.inverse() conf_to_hyp.display() # The expression of the metric tensor in the conformal coordinates is # In[57]: g.display(X_conf.frame(), X_conf) # The immersion of $\mathcal{M}$ in $(\mathbb{R}^{2,3},h)$ in terms of the conformal coordinates: # In[58]: Phi.display(X_conf, X23) # In[59]: Riem.display_comp(X_conf.frame(), X_conf, only_nonredundant=True) # Let us draw the grid of hyperbolic coordinates in terms of the conformal ones: # In[60]: graph = X_hyp.plot(X_conf, ambient_coords=(ch, tat), fixed_coords={th: pi/2, ph: pi}, ranges={ta: (-pi,pi), rh: (0,10)}, number_values={ta: 9, rh: 20}, parameters={l:1}, color={ta: 'red', rh: 'grey'}) show(graph, aspect_ratio=0.25) # Same thing for the grid of static coordinates in terms of the conformal ones: # In[61]: graph = X_stat.plot(X_conf, ambient_coords=(ch, tat), fixed_coords={th: pi/2, ph: pi}, ranges={ta: (-pi,pi), R: (0,40)}, number_values={ta: 9, R: 40}, parameters={l:1}, color={ta: 'red', R: 'grey'}) show(graph, aspect_ratio=0.25) # Let us add some geodesics: # In[62]: for geod in null_geods: geod.display(geod.domain().canonical_chart(), X_conf) time_geod.display(time_geod.domain().canonical_chart(), X_conf) # In[63]: for geod in null_geods: graph += geod.plot(X_conf, ambient_coords=(ch,tat), parameters={l:1}, color='green', thickness=2) graph += time_geod.plot(X_conf, ambient_coords=(ch,tat), prange=(-pi, pi), plot_points=200, parameters={l:1}, color='purple', thickness=2) show(graph, aspect_ratio=0.25, ymin=-pi, ymax=pi) # We notice that the null geodesics are straight lines in terms of the conformal coordinates # $(\tau,\chi)$. # ## Conformal metric # Let us call $\Omega^{-2}$ the common factor that appear in the expression of the metric in conformal coordinates: # In[64]: Omega = M.scalar_field({X_conf: cos(ch)/l}, name='Omega', latex_name=r'\Omega') Omega.display() # In[65]: Omega.display(X_hyp) # We introduce the metric $\tilde g = \Omega^2 g$: # In[66]: gt = M.lorentzian_metric('gt', latex_name=r'\tilde{g}') gt.set(Omega^2*g) gt.display(X_conf.frame(), X_conf) # ## Einstein static universe # The Einstein static universe is the manifold $\mathbb{R}\times\mathbb{S}^3$ equipped with a Lorentzian metric equivalent to $\tilde{g}$. We consider here the part $E$ of $\mathbb{R}\times\mathbb{S}^3$ covered by hyperspherical coordinates: # In[67]: E = Manifold(4, 'E') print(E) # In[68]: XE. = E.chart(r'tat:\tilde{\tau} cht:(0,pi):\chi th:(0,pi):\theta ph:(0,2*pi):\phi') XE # In[69]: XE.coord_range() # The conformal completion of AdS spacetime is defined by the map: # In[70]: Psi = M.diff_map(E, {(X_conf, XE): [tat, ch, th, ph]}, name='Psi', latex_name=r'\Psi') print(Psi); Psi.display() # ### Embedding of $E$ in $\mathbb{R}^5$ # For visualization purposes, we introduce the (differentiable, not isometric) embedding $\Phi_E$ of the Einstein cylinder $\mathbb{R}\times\mathbb{S}^3$ in $\mathbb{R}^5$ that follows immediately from the canonical embedding of $\mathbb{S}^3$ in $\mathbb{R}^4$. We introduce $\mathbb{R}^5$ first: # In[71]: R5 = Manifold(5, 'R5', latex_name=r'\mathbb{R}^5') X5. = R5.chart() X5 # and define $\Phi_E$ as # In[72]: PhiE = E.diff_map(R5, {(XE, X5): [tat, cos(cht), sin(cht)*sin(th)*cos(ph), sin(cht)*sin(th)*sin(ph), sin(cht)*cos(th)]}, name='Phi_E', latex_name=r'\Phi_E') print(PhiE); PhiE.display() # In[73]: graphE = XE.plot(X5, ambient_coords=(W,X,T), mapping=PhiE, fixed_coords={th:pi/2, ph:0}, ranges={tat: (-pi,pi), cht: (0,pi)}, number_values=9, color='silver', thickness=0.5, label_axes=False) # phi = 0 graphE += XE.plot(X5, ambient_coords=(W,X,T), mapping=PhiE, fixed_coords={th:pi/2, ph:pi}, ranges={tat: (-pi,pi), cht: (0,pi)}, number_values=9, color='silver', thickness=0.5, label_axes=False) # phi = pi show(graphE, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['W','X','tau']) # ## View of $\mathrm{AdS}_4$ on the Einstein cylinder # # The view is obtained by composing the embeddings # $\Psi:\, \mathcal{M}\rightarrow E$ and $\Phi_E:\, E\rightarrow \mathbb{R}^5$, i.e. by introducing # $$\Theta= \Phi_E\circ \Psi :\ \mathcal{M}\rightarrow \mathbb{R}^5$$ # In[74]: Theta = PhiE * Psi print(Theta) Theta.display() # In[75]: graph = X_stat.plot(X5, ambient_coords=(W,X,T), mapping=Theta, fixed_coords={th: pi/2, ph: 0}, ranges={ta: (-pi,pi), R: (0,40)}, number_values={ta: 9, R: 40}, parameters={l:1}, color={ta: 'red', R: 'grey'}, label_axes=False) # phi = 0 graph += X_stat.plot(X5, ambient_coords=(W,X,T), mapping=Theta, fixed_coords={th: pi/2, ph: pi}, ranges={ta: (-pi,pi), R: (0,40)}, number_values={ta: 9, R: 40}, parameters={l:1}, color={ta: 'red', R: 'grey'}, label_axes=False) # phi = pi graph += graphE # superposing the plot of the Einstein cylinder half_cylinder = parametric_plot3d([sin(ph), cos(ph), ta], (ta, -pi, pi), (ph, 0, pi), color=(1.,1.,0.9)) graph += half_cylinder show(graph, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['W','X','tau']) # In[76]: for geod in null_geods: graph += geod.plot(X5, ambient_coords=(W,X,T), mapping=Theta, parameters={l:1}, color='green', thickness=1, label_axes=False) graph += time_geod.plot(X5, ambient_coords=(W,X,T), mapping=Theta, prange=(-pi, pi), plot_points=100, parameters={l:1}, color='purple', thickness=2, label_axes=False) show(graph, aspect_ratio=1, viewer=viewer3D, online=True, zmin=-pi, zmax=pi, axes_labels=['W','X','tau']) # In[77]: graph1 = graph.rotate((0,0,1), 0.4) show(graph1, aspect_ratio=1, viewer='tachyon', frame=False, figsize=20) # A different cylindrical view of AdS spacetime is obtained by using the coordinates $(T,X,Y)$ of $\mathbb{R}^5$ instead of $(T,W,X)$ as above. Let us draw the grid of conformal # coordinates at $\theta=\pi/2$, with # - red lines as those along which $\tilde{\tau}$ varies at fixed $(\chi,\phi)$ # - grey lines as those along which $\chi$ varies at fixed $(\tilde{\tau},\phi)$ # - orange lines as those along which $\phi$ varies at fixed $(\tilde{\tau},\chi)$ # In[78]: graph = X_conf.plot(X5, ambient_coords=(X,Y,T), mapping=Theta, fixed_coords={th: pi/2}, ranges={tat: (-pi,pi), ch: (0,pi/2), ph:(0,2*pi)}, number_values=6, parameters={l:1}, color={tat: 'red', ch: 'grey', ph: 'orange'}, label_axes=False) graph += graphE show(graph, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['X','Y','tau']) # Let us add the previously considered null (green) and timelike (purple) geodesics, noticing that they all lie in the plane $Y=0$ for they have $\phi=0$ or $\pi$: # In[79]: for geod in null_geods: graph += geod.plot(X5, ambient_coords=(X,Y,T), mapping=Theta, parameters={l:1}, color='green', thickness=1, label_axes=False) graph += time_geod.plot(X5, ambient_coords=(X,Y,T), mapping=Theta, prange=(-pi, pi), plot_points=100, parameters={l:1}, color='purple', thickness=2, label_axes=False) show(graph, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['X','Y','tau']) # ## Poincaré coordinates # The Poincaré coordinates are defined on the open subset $\mathcal{M}_{\rm P}$ of $\mathcal{M}_0$ defined by $U-X>0$ in terms of the canonical immersion $\Phi$ in $\mathbb{R}^{2,3}$. The open subset $\mathcal{M}_{\rm P}$ is usually called the **Poincaré patch** of AdS spacetime and its boundary $U-X=0$ is called the **Poincaré horizon**. # # Given the expression of $\Phi$: # In[80]: Phi.display() # we see that $U-X>0$ is equivalent to each of the following conditions: # # - in hyperboloidal coordinates: # In[81]: Phi.expr(X_hyp, X23)[0] - Phi.expr(X_hyp, X23)[2] > 0 # - in static coordinates: # In[82]: Phi.expr(X_stat, X23)[0] - Phi.expr(X_stat, X23)[2] > 0 # - in conformal coordinates: # In[83]: Phi.expr(X_conf, X23)[0] - Phi.expr(X_conf, X23)[2] > 0 # Since $\chi\in(0,\pi/2)$, we have actually $|\cos(\chi)| = \cos(\chi)>0$ (the lack of simplification of $|\cos(\chi)|$ for such a case will be corrected in a future version of SageMath); hence we declare: # In[84]: MP = M0.open_subset('MP', latex_name=r'\mathcal{M}_{\rm P}', coord_def={X_hyp: cos(ta/l) - tanh(rh)*sin(th)*cos(ph)>0, X_stat: cos(ta/l) - R/sqrt(R^2+l^2)*sin(th)*cos(ph)>0, X_conf: cos(tat) - sin(ch)*sin(th)*cos(ph)>0}) print(MP) # In[85]: print("Coordinate definition of the Poincaré patch in different charts:") for chart in MP.atlas(): show(chart) show(chart._restrictions) # A view of the Poincaré patch on the AdS hyperboloid in $\mathbb{R}^{2,3}$: # In[86]: graph = X_hyp.restrict(MP).plot(X23, mapping=Phi, ambient_coords=(V,X,U), fixed_coords={th: pi/2, ph:0}, ranges={ta:(0,2*pi), rh:(0,2)}, number_values={ta: 24, rh: 11}, color={ta:'red', rh:'grey'}, thickness=2, parameters={l:1}, label_axes=False) graph += X_hyp.restrict(MP).plot(X23, mapping=Phi, ambient_coords=(V,X,U), fixed_coords={th: pi/2, ph:pi}, ranges={ta:(0,2*pi), rh:(0,2)}, number_values={ta: 24, rh: 11}, color={ta:'red', rh:'grey'}, thickness=2, parameters={l:1}, label_axes=False) graph += hyperboloid show(graph, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['V','X','U']) # A view of the Poincaré patch on the Einstein cylinder: # In[87]: graph = X_stat.restrict(MP).plot(X5, ambient_coords=(W,X,T), mapping=Theta, fixed_coords={th: pi/2, ph: 0}, ranges={ta: (-pi,pi), R: (0, 10)}, number_values={ta: 15, R: 20}, parameters={l:1}, color={ta: 'red', R: 'grey'}, label_axes=False) # phi = 0 graph += X_stat.restrict(MP).plot(X5, ambient_coords=(W,X,T), mapping=Theta, fixed_coords={th: pi/2, ph: pi}, ranges={ta: (-pi,pi), R: (0, 10)}, number_values={ta: 15, R: 20}, parameters={l:1}, color={ta: 'red', R: 'grey'}, label_axes=False) # phi = pi graph += graphE + half_cylinder show(graph, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['W','X','tau']) # Let us add the Poincaré horizon: # In[88]: poincare_hor = parametric_plot3d([cos(ch), sin(ch), acos(-sin(ch))-pi], (ch, 0, pi/2), color='green', thickness=2) + \ parametric_plot3d([cos(ch), sin(ch), -acos(-sin(ch))+pi], (ch, 0, pi/2), color='green', thickness=2) + \ parametric_plot3d([cos(ch), -sin(ch), acos(sin(ch))-pi], (ch, 0, pi/2), color='green', thickness=2) + \ parametric_plot3d([cos(ch), -sin(ch), -acos(sin(ch))+pi], (ch, 0, pi/2), color='green', thickness=2) graph += poincare_hor show(graph, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['W','X','tau']) # The Poincaré patch in the alternative cylindrical view of AdS spacetime based on the # $(T,X,Y)$ coordinates of $\mathbb{R}^5$: # In[89]: graph = X_conf.restrict(MP).plot(X5, ambient_coords=(X,Y,T), mapping=Theta, fixed_coords={th: 0.9*pi/2}, ranges={tat: (-pi,pi), ch: (0,pi/2), ph:(0,2*pi)}, number_values=6, parameters={l:1}, color={tat: 'red', ch: 'grey', ph: 'orange'}, label_axes=False) show(graph+graphE, aspect_ratio=(1,1,0.5), viewer=viewer3D, online=True, axes_labels=['X','Y','tau']) # We define the Poincaré coordinates $(t,x,y,u)$ on $\mathcal{M}_{\rm P}$ as # In[90]: X_Poinc. = MP.chart('t x y u:(0,+oo)') X_Poinc # In[91]: X_Poinc.coord_range() # The link between the conformal coordinates and the Poincaré ones is # In[92]: conf_to_Poinc = X_conf.restrict(MP).transition_map(X_Poinc, [l*sin(tat)/(cos(tat) - sin(ch)*sin(th)*cos(ph)), l*sin(ch)*sin(th)*sin(ph)/(cos(tat) - sin(ch)*sin(th)*cos(ph)), l*sin(ch)*cos(th)/(cos(tat) - sin(ch)*sin(th)*cos(ph)), l*(cos(tat) - sin(ch)*sin(th)*cos(ph))/cos(ch)]) conf_to_Poinc.display() # In[93]: conf_to_Poinc.set_inverse(atan2(2*l*t, x^2+y^2-t^2+l^2*(1+l^2/u^2)), acos(2*l^3/u/sqrt((x^2+y^2-t^2+l^2*(1+l^2/u^2))^2 + 4*l^2*t^2)), acos(2*l*y/sqrt((x^2+y^2-t^2+l^2*(1+l^2/u^2))^2 + 4*l^2*(t^2-l^4/u^2))), atan2(2*l*x, x^2+y^2-t^2-l^2*(1-l^2/u^2)), verbose=True) # The test is passed, modulo some lack of simplification in the `arctan2` and `arccos` functions. # In[94]: conf_to_Poinc.inverse().display() # The isometric immersion $\Phi$ expressed in terms of Poincaré coordinates: # In[95]: Phi.restrict(MP).display(X_Poinc, X23) # We see that the coordinate $u$ is simply $U-X$: # In[96]: U1 = Phi.restrict(MP).expr(X_Poinc, X23)[0] X1 = Phi.restrict(MP).expr(X_Poinc, X23)[2] (U1 - X1).simplify_full() # so that the Poincaré horizon corresponds to $u\rightarrow 0$. # ### Metric in Poincaré coordinates # # Let us ask Sage to compute the metric components in terms of the Poincaré coordinates: # In[97]: g.display(X_Poinc.frame(), X_Poinc) # We notice that the metric restricted to the hypersurfaces $u=\mathrm{const}$ (i.e. the intersection of the hyperboloid with hyperplanes $U-X = \mathrm{const}$) is nothing but the Minkowski metric (up to some constant factor $u^2/\ell^2$): # $$ \left. g \right| _{u=\mathrm{const}}= \frac{u^2}{\ell^2} \left( # -\mathrm{d}t\otimes\mathrm{d}t + # \mathrm{d}x\otimes\mathrm{d}x + \mathrm{d}y\otimes\mathrm{d}y \right).$$ # $(t,x,y)$ appear then as Minkowskian coordinates of these hypersurfaces. We may say that $\mathcal{M}_{\rm P}$ is sliced by a family, parametrized by $u$, of flat 3-dimensional spacetimes. # In[98]: Poinc_to_stat = stat_to_conf.inverse().restrict(MP) * conf_to_Poinc.inverse() Poinc_to_stat.display() # Plot of the Poincaré coordinates $(t,x)$ in terms of the static coordinates $(\tau, R)$ for $y=0$ and $u=1$: # In[99]: graph = X_Poinc.plot(X_stat.restrict(MP), ambient_coords=(R, ta), fixed_coords={y:0, u:1}, number_values=9, parameters={l:1}, plot_points=200, color={t: 'red', x: 'gold', y: 'orange', u: 'cyan'}) show(graph) # Plot of the Poincaré coordinates $(t,u)$ in terms of $(U,V,X)$ for $(x,y)=(0,0)$: # In[100]: graph = X_Poinc.plot(X23, mapping=Phi.restrict(MP), ambient_coords=(V,X,U), fixed_coords={x:0, y:0}, ranges={t:(-1,1), x:(-1,1), y:(-1,1), u:(0.1, 6)}, number_values=13, color={t:'red', x:'gold', y:'orange', u: 'cyan'}, thickness=1, parameters={l:1}, label_axes=False) graph += hyperboloid show(graph, aspect_ratio=1, viewer=viewer3D, online=True, axes_labels=['V','X','U']) # Plot of the Poincaré coordinates $(t,x,u)$ in terms of $(T,X,Y)$ for $y=0$: # - the red lines are those along which $t$ varies at fixed $(x,u)$ # - the gold lines are those along which $x$ varies at fixed $(t,u)$ # - the cyan lines are those along which $u$ varies at fixed $(t,x)$ # In[101]: graph = X_Poinc.plot(X5, ambient_coords=(X,Y,T), mapping=Theta.restrict(MP), fixed_coords={y:0}, ranges={t:(-3,3), x:(-3,3), y:(-3,3), u:(0.01, 6)}, number_values=7, color={t:'red', x:'gold', y:'orange', u: 'cyan'}, parameters={l:1}, label_axes=False) graph += graphE show(graph, aspect_ratio=1, viewer=viewer3D, online=True) # ### Variant of Poincaré coordinates # # Instead of $u$, we may use the coordinate # $$ z = \frac{\ell^2}{u}$$ # In[102]: X_Poinc_z. = MP.chart('t x y z:(0,+oo)') X_Poinc_z # In[103]: X_Poinc_z.coord_range() # In[104]: Poinc_to_Poinc_z = X_Poinc.transition_map(X_Poinc_z, [t, x, y, l^2/u]) Poinc_to_Poinc_z.display() # In[105]: Poinc_to_Poinc_z.inverse().display() # In terms of the coordinates $(t,x,y,z)$, the AdS metric looks like the metric of the 4-dimensional hyperbolic space in ["half-plane" Poincaré coordinates](http://nbviewer.jupyter.org/github/sagemanifolds/SageManifolds/blob/master/Worksheets/v1.0/SM_hyperbolic_plane.ipynb), except for the change of signature from $(+,+,+,+)$ to $(-,+,+,+)$: # In[106]: g.display(X_Poinc_z.frame(), X_Poinc_z) # This justifies the name *Poincaré coordinates* given to $(t,x,y,u)$. # The isometric immersion in $\mathbb{R}^{2,3}$ in terms of the Poincaré coordinates $(t,x,y,z)$: # In[107]: Phi.restrict(MP).display(X_Poinc_z, X23) # ### Exponential Poincaré coordinates # # Another variant of Poincaré coordinates is by using $r$ instead of $u$, such that # $$ u = \ell e^{r/\ell}$$ # In[108]: X_Poinc_exp. = MP.chart() X_Poinc_exp # In[109]: X_Poinc_exp.coord_range() # In[110]: Poinc_to_Poinc_exp = X_Poinc.transition_map(X_Poinc_exp, [t, x, y, l*ln(u/l)]) Poinc_to_Poinc_exp.display() # In[111]: Poinc_to_Poinc_exp.inverse().display() # In[112]: g.display(X_Poinc_exp.frame(), X_Poinc_exp) # The isometric immersion in $\mathbb{R}^{2,3}$ in terms of the coordinates $(t,x,y,r)$: # In[113]: Phi.restrict(MP).display(X_Poinc_exp, X23) # ## Summary # # 10 charts have been defined on the $\mathrm{AdS}_4$ spacetime: # In[114]: M.atlas() # There are actually 7 main charts, the other ones being subcharts: # In[115]: M.top_charts() # Except for $(\tau,x_\rho,y_\rho,z_\rho)$ (which has been introduced only for graphical purposes), the expression of the metric tensor in each of these chart is # In[116]: for chart in M.top_charts(): try: show(g.display(chart.frame(), chart)) except: pass # In[ ]: