This Jupyter/SageMath worksheet implements some computations of the article
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
Let us declare the spacetime $M$ as a 5-dimensional manifold:
M = Manifold(5, 'M')
print M
We introduce a first coordinate system on $M$:
X0.<t,x,y1,y2,R> = M.chart(r't x y1:y_1 y2:y_2 R:\tilde{r}:(0,+oo)')
X0
Let us consider the following Lifshitz-symmetric metric, parametrized by some real number $\nu$:
g = M.lorentzian_metric('g')
var('nu', latex_name=r'\nu', domain='real')
g[0,0] = -R^(2*nu)
g[1,1] = R^(2*nu)
g[2,2] = R^2
g[3,3] = R^2
g[4,4] = 1/R^2
g.display()
A matrix view of the metric components:
g[:]
This metric is invariant under the Lifshitz scaling $$ (t,x,y_1,y_2,\tilde r) \longmapsto \left(\lambda^\nu t, \lambda^\nu x, \lambda y_1, \lambda y_2, \frac{\tilde r}{\lambda} \right)$$
Let us introduce a second coordinate system on $M$:
X.<t,x,y1,y2,r> = M.chart('t x y1:y_1 y2:y_2 r')
X
and relate it to the previous one by the transformation $r=\ln\tilde r$:
X0_to_X = X0.transition_map(X, [t, x, y1, y2, ln(R)])
X0_to_X.display()
The inverse coordinate transition is computed by means of the method inverse()
:
X_to_X0 = X0_to_X.inverse()
X_to_X0.display()
At this stage, the manifold's atlas defined by the user is
M.atlas()
and the list of defined vector frames defined is
M.frames()
The expression of the metric in terms of the new coordinates is
g.display(X.frame(), X)
or, in matrix view:
g[X.frame(),:,X]
To access to a particular component, we have to specify (i) the frame w.r.t. which it is defined and (ii) the coordinates in which the component is expressed:
g[X.frame(),0,0,X]
g[X.frame(),0,0] # the default chart is used
From now on, let us consider the coordinates $X = (t,x,y_1,y_2,r)$ as the default ones on the manifold $M$:
M.set_default_chart(X)
M.set_default_frame(X.frame())
Then
g.display()
g[:]
g[0,0]
g.display_comp()
The Riemann tensor is
Riem = g.riemann()
print Riem
Riem.display_comp(only_nonredundant=True)
The Ricci tensor:
Ric = g.ricci()
print Ric
Ric.display()
Ric.display_comp()
The Ricci scalar:
Rscal = g.ricci_scalar()
print Rscal
Rscal.display()
We note that the Ricci scalar is constant.
Let us consider a model based on the following action, involving a dilaton scalar field $\phi$ and a Maxwell 2-form $F$:
$$ S = \int \left( R(g) + \Lambda - \frac{1}{2} \nabla_m \phi \nabla^m \phi - \frac{1}{4} e^{\lambda\phi} F_{mn} F^{mn} \right) \sqrt{-g} \, \mathrm{d}^5 x \qquad\qquad \mbox{(1)}$$where $R(g)$ is the Ricci scalar of metric $g$, $\Lambda$ is the cosmological constant and $\lambda$ is the dilatonic coupling constant.
We consider the following ansatz for the dilaton scalar field $\phi$: $$ \phi = \frac{1}{\lambda} \left( 4 r + \ln\mu \right),$$ where $\mu$ is a constant.
var('mu', latex_name=r'\mu', domain='real')
var('lamb', latex_name=r'\lambda', domain='real')
phi = M.scalar_field({X: (4*r + ln(mu))/lamb},
name='phi', latex_name=r'\phi')
phi.display()
The 1-form $\mathrm{d}\phi$ is
dphi = phi.differential()
print dphi
dphi.display()
dphi[:] # all the components in the default frame
We consider the following ansatz for $F$: $$ F = \frac{1}{2} q \, \mathrm{d}y_1\wedge \mathrm{d}y_2, $$ where $q$ is a constant.
Let us first get the 1-forms $\mathrm{d}y_1$ and $\mathrm{d}y_2$:
X.coframe()
dy1 = X.coframe()[2]
dy2 = X.coframe()[3]
print dy1
print dy2
dy1, dy2
Then we can form $F$ according to the above ansatz:
var('q', domain='real')
F = q/2 * dy1.wedge(dy2)
F.set_name('F')
print F
F.display()
By construction, the 2-form $F$ is closed (since $q$ is constant):
print(F.exterior_derivative())
F.exterior_derivative().display()
Let us evaluate the square $F_{mn} F^{mn}$ of $F$:
Fu = F.up(g)
print Fu
Fu.display()
F2 = F['_{mn}']*Fu['^{mn}'] # using LaTeX notations to denote contraction
print F2
F2.display()
We shall also need the tensor $\mathcal{F}_{mn} := F_{mp} F_n^{\ \, p}$:
FF = F['_mp'] * F.up(g,1)['^p_n']
print FF
FF.display()
The tensor field $\mathcal{F}$ is symmetric:
FF == FF.symmetrize()
Therefore, from now on, we set
FF = FF.symmetrize()
Let us first introduce the cosmological constant:
var('Lamb', latex_name=r'\Lambda', domain='real')
From the action (1), the field equation for the metric $g$ is $$ R_{mn} + \frac{\Lambda}{3} \, g - \frac{1}{2}\partial_m\phi \partial_n\phi -\frac{1}{2} e^{\lambda\phi} F_{mp} F^{\ \, p}_n + \frac{1}{12} e^{\lambda\phi} F_{rs} F^{rs} \, g_{mn} = 0 $$ We write it as
EE == 0
with EE
defined by
EE = Ric + Lamb/3*g - 1/2* (dphi*dphi) - 1/2*exp(lamb*phi)*FF \
+ 1/12*exp(lamb*phi)*F2*g
EE.set_name('E')
print EE
EE.display_comp(only_nonredundant=True)
We note that EE==0
leads to only 3 independent equations:
eq1 = (EE[0,0]/exp(2*nu*r)).expr()
eq1
eq2 = (EE[2,2]/exp(2*r)).expr()
eq2
eq3 = EE[4,4].expr().expand()
eq3
First we evaluate $\nabla_m \nabla^m \phi$:
nab = g.connection()
print nab
nab
box_phi = nab(nab(phi).up(g)).trace()
print box_phi
box_phi.display()
From the action (1), the field equation for $\phi$ is $$ \nabla_m \nabla^m \phi = \frac{\lambda}{4} e^{\lambda\phi} F_{mn} F^{mn}$$ We write it as
DE == 0
with DE
defined by
DE = box_phi - lamb/4*exp(lamb*phi) * F2
print DE
DE.display()
Hence the dilaton field equation provides a fourth equation:
eq4 = DE.expr().expand()
eq4
From the action (1), the field equation for $F$ is $$ \nabla_m \left( e^{\lambda\phi} F^{mn} \right)= 0 $$ We write it as
ME == 0
with ME
defined by
ME = nab(exp(lamb*phi)*Fu).trace(0,2)
print ME
ME.display()
We get identically zero; indeed the tensor $\nabla_p (e^{\lambda\phi} F^{mn})$ has a vanishing trace, as we can check:
nab(exp(lamb*phi)*Fu).display()
We have 4 equations involving the constants $\lambda$, $\mu$, $\nu$, $q$ and $\Lambda$:
eq1 == 0
eq2 == 0
eq3 == 0
eq4 == 0
eqs = [eq1, eq2, eq3, eq4]
neqs = [eq.subs(nu=1) for eq in eqs]
[eq == 0 for eq in neqs]
solve([eq == 0 for eq in neqs], lamb, mu, Lamb, q)
Hence there is no solution for $\mathrm{AdS}_5$ with the above ansatz.
neqs = [eq.subs(nu=2) for eq in eqs]
[eq == 0 for eq in neqs]
solve([eq == 0 for eq in neqs], lamb, mu, Lamb, q)
Hence there are two families of solutions, each famility being parametrized by e.g. $q$. Indeed, in the above writing, $r_1$ and $r_2$ stand for arbitrary parameters (nothing to do with the coordinate $r$).
neqs = [eq.subs(nu=4) for eq in eqs]
[eq == 0 for eq in neqs]
solve([eq == 0 for eq in neqs], lamb, mu, Lamb, q)
Hence there are two families of solutions, each family being parametrized by e.g. $q$. Note that, as above, $r_i$, with $i$ an integer, stands for an arbitrary parameter (nothing to do with the coordinate $r$).
We add a blackening factor $f(r)$ to the metric; i.e. we declare a new metric $g$ according to
g = M.lorentzian_metric('g')
ff = function('f')(r)
g[0,0] = -ff*exp(2*nu*r)
g[1,1] = exp(2*nu*r)
g[2,2] = exp(2*r)
g[3,3] = exp(2*r)
g[4,4] = 1/ff
g.display()
The Ricci tensor of $g$ is
Ric = g.ricci()
print Ric
Ric.display_comp()
By construction, the 2-form $F$ does not depend on $g$; hence there is no need to reevaluate it:
F.display()
On the contrary, we need to reevaluate its metric dual, in order to compute $F^2 := F_{mn} F^{mn}$:
Fu = F.up(g)
print Fu
Fu.display()
F2 = F['_{mn}']*Fu['^{mn}'] # using LaTeX notations to denote contraction
print F2
F2.display()
Simlarly, we need to reevaluate $\mathcal{F}_{mn} := F_{mp} F_n^{\ \, p}$:
FF = F['_mp'] * F.up(g,1)['^p_n']
print FF
FF.display()
FF == FF.symmetrize()
FF = FF.symmetrize()
The new Einstein equation is
EE = Ric + Lamb/3*g - 1/2* (dphi*dphi) - 1/2*exp(lamb*phi)*FF \
+ 1/12*exp(lamb*phi)*F2*g
EE.set_name('E')
print EE
EE.display_comp(only_nonredundant=True)
EE[2,2] == EE[3,3]
There are 4 independent components:
eq0 = EE[0,0]/exp(2*nu*r)
eq0
eq1 = EE[1,1]/exp(2*nu*r)
eq1
eq2 = EE[2,2]/exp(2*r)
eq2
eq3 = EE[4,4]*lamb^2*f(r)
eq3
The dilaton field equation becomes
nab = g.connection()
box_phi = nab(nab(phi).up(g)).trace()
print box_phi
box_phi.display()
DE = box_phi - lamb/4*exp(lamb*phi) * F2
DE.display()
eq4 = DE.coord_function()*lamb
eq4
The Maxwell equation is still identically satisfied:
ME = nab(exp(lamb*phi)*Fu).trace(0,2)
print ME
ME.display()
The Einstein equation + the dilaton field equation yields a system of 5 equations (eq0, eq1, eq2, eq3, eq4).
Let us show that a solution is obtained for $\nu=2$ and $\nu=4$ with the following specific form of the blackening function:
$$ f(r) = 1 - m e^{-(2\nu +2)r}, $$where $m$ is a constant.
To this aim, we declare
var('m', domain='real')
fm(r) = 1 - m*exp(-(2*nu+2)*r)
fm
and substitute this function for $f(r)$ in all the equations:
eq0m = eq0.expr().substitute_function(f, fm).simplify_full()
eq0m
eq0m = (eq0m * exp(2*nu*r+2*r)).simplify_full()
eq0m
eq1m = eq1.expr().substitute_function(f, fm).simplify_full()
eq1m
eq2m = eq2.expr().substitute_function(f, fm).simplify_full()
eq2m
eq3m = eq3.expr().substitute_function(f, fm).simplify_full()
eq3m
eq3m = (eq3m * exp(2*nu*r+2*r)).simplify_full()
eq3m
eq4m = eq4.expr().substitute_function(f, fm).simplify_full()
eq4m
eqs = [eq0m, eq1m, eq2m, eq3m, eq4m]
neqs = [eq.subs(nu=2).simplify_full() for eq in eqs]
[eq == 0 for eq in neqs]
solve([eq == 0 for eq in neqs], lamb, mu, Lamb, q, m, r)
In the above solutions, $r_i$, with $i$ an integer, stands for an arbitrary parameter.
We recover the same solution for $\lambda$, $\Lambda$ and $\mu q^2$ as in Sec. 1 (i.e. without any black brane). The value of $m$ can be chosen arbitraly. The solution of Sec. 1 corresponds to $m=0$.
neqs = [eq.subs(nu=4).simplify_full() for eq in eqs]
[eq == 0 for eq in neqs]
solve([eq == 0 for eq in neqs], lamb, mu, Lamb, q, m, r)
In the above solutions, $r_i$, with $i$ an integer, stands for an arbitrary parameter.
We recover the same solution for $\lambda$, $\Lambda$ and $\mu q^2$ as in Sec. 1 (i.e. without any black brane). The value of $m$ can be chosen arbitraly. The solution of Sec. 1 corresponds to $m=0$.