Introduction to xCoba

Downloading and Installing xAct

Visit the page: http://www.xact.es
Follow installation instructions on http://www.xact.es/download.html
See also my “Introduction to xTensor” video: https://youtu.be/pQwrKF08Xps

Linux: 
1. Download the tarball xAct_V.tgz (V is the version number)
2. sudo -i ; cd /usr/share/Mathematica/Applications/; tar xvfz ~/Downloads/xAct_V.tgz
Windows:
1. Download the zip file xAct_V.zip (V is the version number)
2. unzip its contents in C:\Program Files\Wolfram Research\Mathematica\<version>\AddOns\Applications\

Read the documentation:
http://www.xact.es/documentation.html
If you want to use xCoba, you will not avoid reading the full documentation. Better earlier than later:  xCobaDoc.nb

The documentation is also installed locally, most likely in:
Linux:          /usr/share/Mathematica/Applications/xAct/Documentation/English/
Windows: C:\Program Files\Wolfram Research\Mathematica\<version>\AddOns\Applications\xAct\Documentation\English

Explore the documentation in xCobaDoc.nb.... Make a copy to the notebook, so that you can play with it.
cp /usr/share/Mathematica/Applications/xAct/Documentation/English/xCobaDoc.nb .

Start an xCoba session

If you are already running a Mathematica session, esp. if you have loaded xTensor, xAct, ..., make a call to Quit[] before the loading of the package:
Quit[]; Needs[“xAct`xCoba`”]

Needs["xAct`xCoba`"]

Define a manifold: you need a name, its dimension, and the set of indices that you will use:
Same as in xTensor: it also defines  the associated Tangent Bundle  Tangent<Name> 
In our case: M and TangentM

DefManifold[M,4,{λ,μ,ν,ρ,σ,α,β,γ,δ}];

dimM = DimOfManifold[M];dimM1 = dimM-1;

Definition of a chart

For xCoba, a chart is synonymous to a coordinate basis. 
A set of scalar fields (in the sense of xTensor) is defined with it, the coordinates.

The basis of the chart gets its color, this distinguishes it in the output, when there are more bases present, from abstract indices etc.

Non coordinate bases can also be defined - not presented here -, the main difference being that their “partial derivative” does not commute on functions (there is torsion, their Lie bracket is non vanishing etc). The terminology for “partial derivative” in xCoba is “Parallel Derivative”.

In the definition below:
ch:  the name of the chart (or coordinate basis)
{0,1,2,3}: the allowed values of indices. There is no restriction except they have to be as many as dimM
{t[],r[],θ[],ϕ[]}: the names of the scalars that will be used for coordinates. Note the (compulsory) square brackets.
ChartColor: the color used for the indices of the basis ch. If omitted, a default color is used

DefChart[ch,M,{0,1,2,3},{t[],r[],θ[],ϕ[]},ChartColor->Blue]

We can use tensor objects, as in xTensor. The coordinates have been defined as scalars t[ ], r[ ], θ[ ], ϕ[ ], and can be used in any expression.

xTensor expressions will be treated as abstract, non coordinated objects:

DefConstantSymbol[mass     ,PrintAs->"M"];
DefScalarFunction[scalar,PrintAs->"Φ"];
DefScalarFunction[s ];
DefTensor[w[μ],M];
{mass, mass scalar[], ((2 mass)/(r[])),s[] scalar[] r[] w[μ]}

The basic object used as a tensor with components, is a CTensor object, defined by the CTensor function.
After that, the object can be used as an abstract tensor, or perform contractions w.r.t. chosen indices.

In the following example, v is a vector with:
{2, -1, 3, 4}: its components
{ch}:              the basis w.r.t. the components are calculated. For a 1-form, we would have used {-ch}.

v=CTensor[{2,-1,3,4},{ch}]

StandardForm of the vector. It is printed with one abstract index.
This is as an xTensor object, except that the head displays the components. 
That the components refer to the ch-basis is indicated by the blue color (the basis’ color)

v[μ]

{StandardForm[v[μ]],TraditionalForm[v[μ]],OutputForm[v[μ]],InputForm[v[μ]],FullForm[v[μ]]}

A CTensor can take 3 types of indices:
Type                                      Example
Abstract        index:                 μ
Basis               index:                {μ,ch}                         ch is the name of the chart the index refers to
Component index:                {0,ch}                         the number must be in the list of allowed index values {0,1,2,3} defined for the chart ch

The following expands (v^μ) as a liner combination of the basis vectors of the chart ch. The blue numbers indicate that they are the (coordinate) basis vectors of ch. The index μ is abstract (abstract index notation).

v[{μ,ch}]

v[{α,ch}],  α=0,1,2,3  gives the respective components:

{v[{0,ch}],v[{1,ch}],v[{2,ch}],v[{3,ch}]}

Example of a one form:

ω=CTensor[{-2,1,-4,3},{-ch}]

Output form of the 1-form. It is printed with one abstract index.
This is as an xTensor object, except that the head displays the components. 
That the components refer to the ch-basis is indicated by the blue color (the basis’ color)

ω[-μ]

Here, we see the dual basis used in the expansion:

ω[{-μ,-ch}]

Notice, there is no - (minus sign) when a component index is used. The (-) must be put in front of the basis:

Table[ω[{α,-ch}],{α,0,3}]

If omitted, xCoba does not know what to do. This will change when we will define a metric.

Table[ω[{α,ch}],{α,0,3}]

We can do contractions:

ω[-μ] v[μ]

We can contract with an abstract tensor. The output form of the contraction is the same as in xTensor, except for the head of the CTensor object that displays the components.

ω[-μ] w[μ]

As a linear combination of the basis covectors

ω[-μ] w[μ]//ToBasisExpand

An an expression using components of (w^μ) in the ch-basis. The color of the indices indicate the basis that the components correspond to.

ω[-μ] w[μ]//ToBasisExpand //ContractBasis

We can do ordinary tensor algebra, using the xTensor notation:

{3 v[μ], 7 v[μ]+ 2 w[μ], v[μ] v[ν], v[μ] w[ν], ω[-μ] v[ν]}

{3 v[μ], 7 v[μ]+ 2 w[μ], v[μ] v[ν], v[μ] w[ν], ω[-μ] v[ν]}//ToBasisExpand

v[μ] w[ν]//ToBasisExpand//ContractBasis

ω[-μ] w[ν]//ToBasisExpand//ContractBasis

We can assign CTensors with “=”

u1= ((2 mass)/(r[])) v

ω[-μ] u1[μ]

We have to convert w to a CTensor object to make the assignment.

ToCTensor[w,{ch}]

w remains an xTensor abstract vector

w[μ]

But we can use ToCTensor to construct more complicated CTensor expressions

u =(1-((2 mass)/(r[])) ) ToCTensor[w,{ch}]

ω[-μ] u[μ]

More complicated expressions. Notice the [ ] when a scalar is used.

scalar[]  ToCTensor[w,{ch}] /(((r[])^2)((Sin[θ[]])^2))

Contract directly:

(scalar[]  ToCTensor[w,{ch}] /(((r[])^2)((Sin[θ[]])^2)))[μ] ω[-μ]

A (0,2) CTensor:

B = CTensor[{
{1,2,3,4},
{2,2,5,6},
{3,5,3,7},
{4,6,7,4}
},{-ch,-ch}]

B[-μ,-ν]

B[-μ,-ν]//ToBasisExpand

{B[-μ,-ν] v[μ],
B[-μ,-ν] v[μ]//ToBasisExpand}

{B[-μ,-ν] v[μ]v[ν],
B[-μ,-ν] v[μ]w[ν],
B[-μ,-ν] v[μ]w[ν]//ToBasisExpand,
B[-μ,-ν] v[μ]w[ν]//ToBasisExpand//ContractBasis}

This is a 1-form:

2 s[] B[-μ,-ν] v[μ] + 7 scalar[] ω[-ν]//ToBasisExpand

The Metric

To define a metric, we fist have to define a symmetric (0,2)-CTensor object:

$Assumptions = mass > 0 && r[] > 2 mass && 0 < θ[] < 2π && 0 < ϕ[] < 2 π && t[] ∈ Reals;

g=CTensor[
DiagonalMatrix[
{-1+2mass/r[],1/(1-2mass/r[]),r[]^2,r[]^2Sin[θ[]]^2}
],{-ch,-ch}]

{g[-μ,-ν],
g[-μ,-ν]//ToBasisExpand}

We declare (Subscript[g, μν]) to be the metric on the chart ch using the SetCMetric function. We have to declare its signature
SignatureOfMetric -> {n1,n2,n3}  
n1 = number of (+1)
n2= number of (-1)
n3= number of ( 0)   - degenerate metrics

SetCMetric[g,ch,SignatureOfMetric-> {3,1,0}]

The covariant derivative, a Levi-Civita connection (compatible with g and torsion free) is defined by CovDOfMetric.

Notice that a connection in xCoba is an object with CCovD head. It includes CTensor information for Christoffel symbols and the metric itself. PDch is the partial derivative of the ch-chart.

We will do connection calculations later.

cd=CovDOfMetric[g]

An ϵ-Levi-Civita tensor is automatically defined:

epsilon[g]

See its component structure:

epsilon[g]//Normal//Simplify

The determinant of the metric is in Determinant[g,ch]:  It has weight 2, so we see the two blue tildes above its value.

{Determinant[g,ch],Determinant[g,ch][]}

The value of the determinant can be obtained directly using Mathematica’s Det and ComponentArray to obtain a matrix:
(do not present at this point, show later with ComponentArray)

Det[ComponentArray[g[{-μ,-ch},{-ν,-ch}]]]//Simplify

We can raise/lower indices now:

{v[μ],
v[-μ],
v[μ]//ToBasisExpand,
v[-μ]//ToBasisExpand,
ω[-μ]v[μ],
ω[μ]v[-μ]//Simplify,
v[-μ]w[μ]//ToBasisExpand//ContractBasis//Simplify,
B[-μ,-ν],
B[μ,-ν],
B[μ,ν]//Simplify,
B[μ,ν] B[-μ,-ν],
g[μ,ν],
g[-μ,-ν] g[ν,ρ]//Simplify,
g[-μ,-ν] v[ν]-v[-μ]//Simplify,
g[-μ,-ν] w[ν]//ToBasisExpand//ContractBasis
}

Extract components of a tensor using ComponentArray for further manipulation: use Basis indices

{ComponentArray[v[{   μ,  ch}]]//MatrixForm,
ComponentArray[v[{-μ,-ch}]]//MatrixForm,
ComponentArray[w[{   μ,  ch}]]//MatrixForm,
ComponentArray[u[{   μ,  ch}]]//MatrixForm,
ComponentArray[B[{-μ,-ch},{-ν,-ch}]]//MatrixForm,
ComponentArray[B[{-μ,-ch},{  ν,   ch}]]//MatrixForm,
ComponentArray[B[{-μ,-ch},{-ν,-ch}]v[{   μ,  ch}]//ContractBasis]//MatrixForm,
ComponentArray[B[{  μ,   ch},{-ν,-ch}]v[{-μ,-ch}]//ContractBasis//Simplify]//MatrixForm
}

Tensor products:

{ComponentArray[v[{   μ,  ch}]v[{   ν,  ch}]]//MatrixForm,
ComponentArray[v[{   μ,  ch}]w[{   ν,  ch}]]//MatrixForm,
ComponentArray[w[{   μ,  ch}]w[{   ν,  ch}]]//MatrixForm
}

Det[ComponentArray[g[{-μ,-ch},{-ν,-ch}]]]//Simplify

Specific components, using component indices:

Print[
"(v^1)  = ",v[{1,-ch}],"\n",
"\!\(\*SubscriptBox[\(g\), \(\(22\)\(\\ \)\)]\) = ",g[{2,-ch},{2,-ch}],"\n",
"g   = ",Table[g[{i,-ch},{i,-ch}],{i,0,3}],"\n",
"(g^(-1)) = ", Table[g[{i,   ch},{i,   ch}],{i,0,3}]
]

Use MakeRule to make substitutions:

uwvrule = MakeRule[{w[μ],v[μ]}];
dwvrule = MakeRule[{w[-μ],v[-μ]}];
{w[-μ] w[μ],
w[-μ] w[μ] /. uwvrule,,
w[-μ] w[μ] /. dwvrule,
w[-μ] w[μ] /. uwvrule /. dwvrule //Simplify
}

ctrule = MakeRule[{w[μ],CTensor[{scalar[],s[],((r[])^2)Sin[θ[]],(E^(t[]))},{ch}][μ]}];
{w[μ],
w[μ]              /.ctrule//ToBasisExpand,
w[μ] ω[-μ] /.ctrule}

ξ = CTensor[{(1/(Sqrt[1-((2 mass)/(r[]))])),(Sqrt[(1-((2 mass)/(r[])))]),r[],r[] Cos[θ[]]      },{-ch}];
F = CTensor[
{
{0                    ,1-((2 mass)/(r[])),0,Cos[θ[]]},
{-1+((2 mass)/(r[])),0                  , 0,        0       },
{0                    , 0                 , 0 ,       0      },
{-Cos[θ[]] ,0                   ,0 ,         0     }
},{ ch, ch}];
{ComponentArray[ξ[{-μ,-ch}]]//MatrixForm,ComponentArray[F[{μ,ch},{ν,ch}]]//MatrixForm}

antisymmetric × symmetric = 0

{
F[α,β] ξ[-α]ξ[-β] //Simplify, 
F[μ,ν] B[-μ,-ν]//Simplify,
epsilon[g][-μ,-ν,-ρ,-σ] B[μ,ν],
epsilon[g][-μ,-ν,-ρ,-σ] F[μ,ν]//Simplify,
epsilon[g][-μ,-ν,-ρ,-σ] F[μ,ν]F[ρ,σ]//Simplify,
epsilon[g][-μ,-ν,-ρ,-σ] F[μ,ν] u[ρ] u[σ]
}

Covariant Derivatives

Ordinary derivatives:     Use the predefined PDch  (partial derivative)
Notice that a scalar can depend on whatever we want...

{PDch[-μ][v[ν]],PDch[-μ][scalar[r[],t[]]],PDch[-μ][scalar[]]}

Covariant derivative: we defined it using cd  = CovDOfMetric[g]

{cd[-μ][v[μ]],
cd[-μ]@g[-ν,-ρ],
cd[-μ]@g[   ν,  ρ],
cd[-μ]@w[μ],
cd[-μ]@ξ[-ν]//Simplify,,
cd[-μ]@F[ν,ρ]//Simplify,
cd[-μ]@F[μ,ν]//Simplify,
cd[-μ] @ cd[-ν] @ v[ρ]//Simplify,
cd[-μ] @ cd[-ν] @ v[μ]//Simplify
}

In order to manipulate components directly, you need to contract with the basis:
(Subscript[∇, μ])(v^ν) (Subscript[((e^μ)), a])((((Subscript[e, ν])))^b)

{CD[-μ]@ v[ν]//ToBasisExpand, CD[-μ][v[ν]] Basis[{0,-ch},μ]Basis[{0,ch},-ν]//ContractBasis}

Table[CD[-μ][v[ν]] Basis[{i,-ch},μ]Basis[{j,ch},-ν]//ContractBasis,{i,0,3},{j,0,3}]//MatrixForm

Christoffel[cd,PDch][μ,-ν,-ρ]

Christoffel[cd,PDch][-μ,-ν,-ρ]

Christoffel[cd,PDch][-μ,-ν,-ρ] v[ν] v[ρ]//Simplify

ComponentArray[Christoffel[cd,PDch][{μ,ch},{-ν,-ch},{-ρ,-ch}]]//MatrixForm

Curvature

Riemann[cd][-μ,-ν,-ρ,σ]

Ricci[cd][-μ,-ν]

RicciScalar[cd][]

Torsion[cd][α,-β,-γ]

Einstein[cd][-μ,-ν]

Weyl[cd][-μ,-ν,-ρ,-λ]

Riemann[cd][-μ,-ν,-ρ,-λ] == Weyl[cd][-μ,-ν,-ρ,-λ]

Kretschmann[cd][]

Commutator of derivatives:
[(Subscript[∇, β]),(Subscript[∇, α])] (v^γ)= ((Subscript[R, αβδ])^γ)(v^δ)

Print[
"\!\(TraditionalForm\`\([\*SubscriptBox[\(∇\), \(β\)], \*SubscriptBox[\(∇\), \(α\)]]\)\\ \*SuperscriptBox[\(v\), \(γ\)]\) = ",comm = cd[-β]@cd[-α]@v[γ] -cd[-α]@cd[-β]@v[γ]//Simplify,"\n",
"\!\(TraditionalForm\`\(\(\\ \\ \\ \\ \\ \\ \\ \\ \)\(\*SuperscriptBox[SubscriptBox[\(R\), \(αβδ\)], \(γ\)] \*SuperscriptBox[\(v\), \(δ\)]\)\)\) = ",riem = Riemann[cd][-α,-β,-δ,γ] v[δ],"\n",
"\!\(TraditionalForm\`\([\*SubscriptBox[\(∇\), \(β\)], \*SubscriptBox[\(∇\), \(α\)]]\)\\ \*SuperscriptBox[\(v\), \(γ\)]\) = ((Subscript[R, αβδ])^γ) (v^δ)   is ",riem == comm //Simplify
]

Basis

Coordinate basis:

Table[Basis[{i,-ch},μ],{i,0,dimM1}]

Table[Basis[{i,ch},-μ],{i,0,dimM1}]

BasisArray[-ch][μ]

BasisArray[-ch,-ch][μ,ν] //MatrixForm

Check duality of base:  ((Subscript[e, α])^μ) ((Subscript[e, μ])^β)=((Subscript[δ, a])^β)

Table[
Basis[{i,-ch},μ] Basis[{j,ch},-μ]    //ContractBasis,       {i,0,dimM1},{j,0,dimM1}
]                                                                                       //MatrixForm

The components of tensors are the contractions with respective basis vectors:

(Subscript[ξ, α])=((Subscript[e, α])^σ)(Subscript[ξ, σ]) =ξ((Subscript[e, α]))  ,           (Subscript[B, αβ])=((Subscript[e, α])^μ)((Subscript[e, β])^ν)(Subscript[B, μν])=B((Subscript[e, α]),(Subscript[e, β]))  ,          (v^α)=((Subscript[e, μ])^α)(v^μ)=v((e^α)), ...

{ξ[{1,-ch}], ξ[-μ] Basis[{1,-ch},μ]//ContractBasis,
B[{1,-ch},{2,-ch}],B[-μ,-ν] Basis[{1,-ch},μ] Basis[{2,-ch},ν]//ContractBasis,
v[{1,  ch}], v[μ] Basis[{1,ch},-μ]//ContractBasis}

(∂_μ)·(∂_ν)=(Subscript[g, μν])≡g((∂_μ),(∂_ν))

Table[
g[-μ,-ν] Basis[{i,-ch},μ]Basis[{j,-ch},ν]//ContractBasis,
{i,0,dimM1},{j,0,dimM1}
]//MatrixForm

(Subscript[∇, μ])((Subscript[e, 1])^ν) ,(Subscript[∇, μ])((Subscript[e, ν])^2) ,(Subscript[∇, μ])(((Subscript[e, ν])^2) ((Subscript[e, ρ])^0)), (Subscript[∇, μ])(Subscript[∇, ν])((Subscript[e, ρ])^0)  ,  (Subscript[∇, μ])(Subscript[∇, ν])((Subscript[e, 1])^μ)

{cd[-μ]@Basis[{1,-ch},  ν],
cd[-μ]@Basis[{2,  ch},-ν],
cd[-μ]@(Basis[{2,  ch},-ν]Basis[{0,  ch},-ρ]),
cd[-μ]@cd[-ν]@ Basis[{0,  ch},-ρ],
cd[-μ]@cd[-ν]@ Basis[{1,-ch},μ]//Simplify
}

Acknowledgements

This notebook has been programmed by Konstantinos Anagnostopoulos, Physics Department, National Technical University of Athens, Greece, while he was an instructor of the 4th year undergraduate course "General Relativity and Cosmology". It was created for fun, but it may turn out to be useful to everyone studying the General Theory of Relativity for the first time.
Email: konstant@mail.ntua.gr
Web:    http://physics.ntua.gr/konstant 
It is offered under a GPL/CC BY 4.0 license (in that order, depending on whether they apply on the programming part or the text part of the notebook).