Friedmann equations

This worksheet demonstrates a few capabilities of SageManifolds (version 1.0, as included in SageMath 7.5) in computations regarding cosmological spacetimes with Friedmann-LemaƮtre-Robertson-Walker (FLRW) metrics.

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:

In [1]:
version()
Out[1]:
'SageMath version 7.5.1, Release Date: 2017-01-15'

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

In [2]:
%display latex

We declare the spacetime M as a 4-dimensional manifold:

In [3]:
M = Manifold(4, 'M')
print(M)
4-dimensional differentiable manifold M

We introduce the standard FLRW 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:

In [4]:
fr.<t,r,th,ph> = M.chart(r't r:[0,+oo) th:[0,pi]:\theta ph:[0,2*pi):\phi')
fr
Out[4]:

Assuming that the speed of light c=1, let us define a few variables: Newton's constant $G$, the cosmological constant $\Lambda$, the spatial curvature constant $k$, the scale factor $a(t)$, the fluid proper density $\rho(t)$ and the fluid pressure $p(t)$:

In [5]:
var('G, Lambda, k', domain='real')
a = M.scalar_field(function('a')(t), name='a')
rho = M.scalar_field(function('rho')(t), name='rho')
p = M.scalar_field(function('p')(t), name='p')

The FLRW metric is defined by its components in the manifold's default frame, i.e. the frame associated with the FLRW coordinates:

In [6]:
g = M.lorentzian_metric('g')
g[0,0] = -1
g[1,1] = a*a/(1 - k*r^2)
g[2,2] = a*a*r^2
g[3,3] = a*a*(r*sin(th))^2
g.display()
Out[6]:

A matrix view of the metric components:

In [7]:
g[:]
Out[7]:

The Levi-Civita connection associated with the metric is computed:

In [8]:
nabla = g.connection()
g.christoffel_symbols_display()
Out[8]:

Ricci tensor:

In [9]:
Ricci = nabla.ricci()
Ricci.display()
Out[9]:

Ricci scalar ($R^\mu_{\ \, \mu}$):

In [10]:
Ricci_scalar = g.ricci_scalar()
Ricci_scalar.display()
Out[10]:

The fluid 4-velocity:

In [11]:
u = M.vector_field('u')
u[0] = 1
u.display()
Out[11]:
In [12]:
g(u,u).expr()
Out[12]:

Perfect fluid energy-momentum tensor $T$:

In [13]:
u_form = u.down(g) # the 1-form associated to u by metric duality
T = (rho+p)*(u_form*u_form) + p*g
T.set_name('T')
print(T)
T.display()
Field of symmetric bilinear forms T on the 4-dimensional differentiable manifold M
Out[13]:

The trace of $T$ (we use index notation to denote the double contraction $g^{ab} T_{ab}$):

In [14]:
Ttrace = g.inverse()['^ab']*T['_ab']
Ttrace.display()
Out[14]:

Einstein equation: $R_{\mu \nu} - {1 \over 2} R g_{\mu \nu} + \Lambda g_{\mu \nu} = {8 \pi G} T_{\mu \nu}$

In [15]:
E1 = Ricci - Ricci_scalar/2*g + Lambda*g - (8*pi*G)*T
print("First Friedmann equation:\n")
E1[0,0].expr().expand() == 0
First Friedmann equation:

Out[15]:

Trace-reversed version of the Einstein equation: $R_{\mu \nu} - \Lambda g_{\mu \nu} = {8 \pi G} \left(T_{\mu \nu} - {1 \over 2}T\,g_{\mu \nu}\right)$

In [16]:
E2 = Ricci - Lambda*g - (8*pi*G)*(T - Ttrace/2*g)
print("Second Friedmann equation:\n")
E2[0,0].expr().expand() == 0
Second Friedmann equation:

Out[16]: