0

I'm trying to create a function which receives as inputs a coordinate system $x^\mu$, metric tensor $g_{\mu\nu}$, a general tensor $T$ of rank $n$, and a list $I$ of length $n$ that looks like this:

$$I=(c_1,c_2,\dots,c_n)\quad\quad \forall i\in[1,n]_{\mathbb N}: c_i\in\{\mathrm{u},\mathrm{d}\}$$

which describes the location of the indices of the tensor ($\mathrm{u}$ for up, $\mathrm{d}$ for down). For example - if $T=T^{\mu\ \ \sigma}_{\ \ \nu\rho}$, then $I=(\mathrm{u},\mathrm{d},\mathrm{d},\mathrm{u})$ and $n=4$.

The output of the function should be the covariant derivative of the tensor in the given coordinate system, defined as the following:

$$\nabla_iv^j=\partial_iv^j+\Gamma^j_{\ ik}v^k \\\nabla_iv_j=\partial_iv_j-\Gamma^k_{\ ij}v_k$$

where $\partial_i\equiv{\partial}/{\partial x_i}$, and $\Gamma^i_{\ ij}$ are the Christoffel symbols. The main difficulty here for me is differentiating between the up and down indices. Also, it's not very clear how the ""matrix"" multiplication should be made.

• I did create a function which computes the Christoffel symbols given a metric $g$ and returns them as a tensor of degree 3 (essentially, it returns a matrix of column vectors), but I don't calculating them in a different way which will make the implementation of the covariant derivative function easier.

• I did search for such implementations, but I didn't find any implementations which differ between contravectors and covectors (up and down indices).

Thanks!

Amit Zach
  • 123
  • 4

1 Answers1

2

I do not really understand the problem implementing the definition $$ \begin{align} {(\nabla_{e_c} T)^{a_1 \ldots a_r}}_{b_1 \ldots b_s} = {} &\frac{\partial}{\partial x^c}{T^{a_1 \ldots a_r}}_{b_1 \ldots b_s} \\ &+ \,{\Gamma ^{a_1}}_{dc} {T^{d a_2 \ldots a_r}}_{b_1 \ldots b_s} + \cdots + {\Gamma^{a_r}}_{dc} {T^{a_1 \ldots a_{r-1}d}}_{b_1 \ldots b_s} \\ &-\,{\Gamma^d}_{b_1 c} {T^{a_1 \ldots a_r}}_{d b_2 \ldots b_s} - \cdots - {\Gamma^d}_{b_s c} {T^{a_1 \ldots a_r}}_{b_1 \ldots b_{s-1} d}. \end{align} $$ (taken from wikipedia) in Mathematica

coD[T_,struct_List,q_,\[CapitalGamma]ijk_,c_,ab_List]:=Module[{dim,rank,k,m},
    dim=Length[q];
    rank=Length[ab];
D[T[[##]]&@@ab,q[[c]]]+Sum[
    If[struct[[k]]==="u",
        +Sum[\[CapitalGamma]ijk[[ab[[k]],m,c]]T[[##]]&@@ReplacePart[ab,k->m],{m,1,dim}],
        -Sum[\[CapitalGamma]ijk[[m,ab[[k]],c]]T[[##]]&@@ReplacePart[ab,k->m],{m,1,dim}]
    ]
,{k,1,rank}]

]

should do the trick. I have not checked this extensively but at least for one covariant derivative of a mixed second rank tensor (energy momentum conservation TOV eq.) it works

dim=4;
q={t,r,\[Theta],\[Phi]};
gdd=DiagonalMatrix[{-Exp[\[Nu][r]],Exp[\[Lambda][r]],r^2,Sin[\[Theta]]^2 r^2}];
guu=Inverse[gdd];
\[CapitalGamma]ddd=Table[1/2 (D[gdd[[c,a]],q[[b]]]+D[gdd[[c,b]],q[[a]]]-D[gdd[[a,b]],q[[c]]]),{c,1,dim},{a,1,dim},{b,1,dim}];
\[CapitalGamma]udd=Table[Sum[guu[[c,m]]\[CapitalGamma]ddd[[m,a,b]],{m,1,dim}],{c,1,dim},{a,1,dim},{b,1,dim}];

Tdu=DiagonalMatrix[{-[Rho][r],P[r],P[r],P[r]}]; Sum[coD[Tdu,{"d","u"},q,[CapitalGamma]udd,m,{2,m}],{m,1,4}]//Simplify

Energy conservation

Some tips for writing code concerning Ricci/tensor calculus like this: do not use matrix/vector multiplication but rather write out the sums explicitly to avoid any confusion about placement of indices. Writing a wrapper for tensor-type objects which holds the elements as well as the index structure might also be a good idea to keep the information about the index location and data in one place. E.g.:

ClearAll[tensor,struct]
tensor/:Part[tensor[mat_,struct_List],ab__]:=mat[[ab]]
struct[tensor[mat_,struct_List]]:=struct
MakeBoxes[tensor[mat_,struc_List],StandardForm]:=ToBoxes@StandardForm@mat

gdd=tensor[DiagonalMatrix[{-Exp[[Nu][r]],Exp[[Lambda][r]],r^2,Sin[[Theta]]^2 r^2}],{"d","d"}] struct[%]

tensor object

this would make passing around the index locations for a given object easier and less error prone but is of course not necessary.

N0va
  • 3,370
  • 11
  • 16