By 苏剑林 | October 19, 2016
The Riemann curvature tensor is an extremely important tensor; the space is flat if and only if all its components are zero. It also appears in Einstein's field equations. In short, as long as Riemannian geometry is involved, the Riemann curvature tensor is bound to be the core content. As we have seen, the Riemann curvature tensor has 4 indices, which also means it has $n^4$ components, where $n$ is the dimension of the space. Thus, in 2, 3, and 4-dimensional spaces, it has 16, 81, and 256 components respectively. Clearly, calculating it is quite a painful task. Fortunately, this tensor has many symmetry properties that significantly reduce the number of independent components. Let's analyze this point.
First, let's derive some symmetry properties of the Riemann curvature tensor, which are consistent with classic textbooks. Define: $$R_{\mu\alpha\beta\gamma}=g_{\mu\nu}R^{\nu}_{\alpha\beta\gamma} \tag{50} $$ The reason for defining this quantity relates to the distinction between contravariant and covariant tensors; here we primarily care about the geometric perspective, so we will skip the detailed analysis of tensors. This quantity is called the fully covariant Riemann curvature tensor, sometimes it is also directly called the Riemann curvature tensor, and as long as it does not cause confusion, they are generally not distinguished. Through slightly tedious algebraic derivations (available in general textbooks on differential geometry, Riemannian geometry, or general relativity), we can obtain: $$ \begin{aligned} &R_{\mu\alpha\beta\gamma}=-R_{\mu\alpha\gamma\beta}\\ &R_{\mu\alpha\beta\gamma}=-R_{\alpha\mu\beta\gamma}\\ &R_{\mu\alpha\beta\gamma}=R_{\beta\gamma\mu\alpha}\\ &R_{\mu\alpha\beta\gamma}+R_{\mu\beta\gamma\alpha}+R_{\mu\gamma\alpha\beta}=0 \end{aligned} \tag{51} $$ The first two equations quickly tell us that if $\beta=\gamma$ or $\mu=\alpha$, then $R_{\mu\alpha\gamma\beta}=0$, which is a consequence of antisymmetry. The following counting shows that the number of independent components can be further reduced. We can view each equation as a constraint; for every constraint, the independent components decrease by 1. We need to consider how many independent constraints there are to determine how many independent components exist.
First, $R_{\mu\alpha\beta\gamma}$ can be viewed as an $n \times n$ matrix (the first two indices), where each element of this matrix is itself an $n \times n$ matrix (the last two indices). From $R_{\mu\alpha\beta\gamma}=-R_{\mu\alpha\gamma\beta}$, we know that each element of the matrix is an antisymmetric matrix, thus having only $n(n-1)/2$ independent components. Similarly, from $R_{\mu\alpha\beta\gamma}=-R_{\alpha\mu\beta\gamma}$, we know that as a matrix of matrices, it is also antisymmetric, so there are only $n(n-1)/2$ independent components. That is to say, based on the first two equations, we know the total number of independent components does not exceed $[n(n-1)/2]^2$.
Next, the third and fourth constraints help us further reduce the number of components. $R_{\mu\alpha\beta\gamma}=R_{\beta\gamma\mu\alpha}$ indicates that if we arrange the remaining $[n(n-1)/2]^2$ components into an $n(n-1)/2 \times n(n-1)/2$ matrix, then it is symmetric. In this case, the number of independent components is only: $$\frac{1}{2}\frac{n(n-1)}{2}\left[\frac{n(n-1)}{2}+1\right] \tag{52} $$ The last constraint $R_{\mu\alpha\beta\gamma}+R_{\mu\beta\gamma\alpha}+R_{\mu\gamma\alpha\beta}=0$ targets four distinct indices, because once there is a pair of identical indices, it can be transformed into a linear combination of the first three constraints. Therefore, the number of independent components needs to be reduced by $\binom{n}{4}$: $$\frac{1}{2}\frac{n(n-1)}{2}\left[\frac{n(n-1)}{2}+1\right]-\binom{n}{4}=\frac{n^2(n^2-1)}{12} \tag{53} $$ Thus, in 2, 3, 4, and 5-dimensional spaces, the number of independent components of the Riemann curvature tensor is 1, 6, 20, and 50 respectively. Particularly, in two-dimensional space (i.e., when studying a 2D surface in 3D space), the curvature tensor has only one independent component.
The following code contains errors and belongs to a bug in SymPy; it has been submitted to the official team, please wait for a fix.
Unfortunately, we can only omit the manual calculation of this curvature tensor here; for this tensor, there is no obviously simple calculation method. Using variational methods can simplify the calculation of $\Gamma^{\mu}_{\alpha\beta}$, which in turn indirectly simplifies the calculation of the curvature tensor. A top-down simplified calculation method would require knowledge of exterior calculus, which we cannot cover in this series at present.
However, computationally, using the symbolic calculation library SymPy in Python can help us quickly calculate connection coefficients and the curvature tensor. SymPy is a symbolic computation library for Python, characterized by being compact, open-source, and powerful. Of course, compared to commercial software like Mathematica, it certainly cannot compete in terms of breadth, but in certain specific areas, it can even be superior—"not excelling in comprehensiveness, but in specialization." SymPy has built-in modules specifically for handling differential geometry and tensors, which makes it very convenient to calculate $\Gamma_{\alpha\beta}^{\mu}$ and $R_{\alpha\beta\gamma}^{\mu}$.
A simple code example is as follows:
from sympy.diffgeom import Manifold, Patch, CoordSystem
from sympy.diffgeom import TensorProduct as TP
from sympy.diffgeom import metric_to_Riemann_components as Riemann
from sympy.diffgeom import metric_to_Christoffel_2nd as Christoffel
from sympy import Symbol, Function, latex, sin
n = 2
M = Manifold('M', n)
P = Patch('P', M)
coord = CoordSystem('coord', P, ['x%s'%i for i in range(n)])
x = coord.coord_functions()
dx = coord.base_oneforms()
g = [[1, 0], [0, sin(x[0])**2]]
metric = sum([g[i][j]*TP(dx[i], dx[j]) for i in range(n) for j in range(n)])
C = Christoffel(metric)
R = Riemann(metric)
This is based on 2D spherical coordinates, where n defines the dimension and g defines the metric matrix. If readers want to modify it, they only need to change these two parameters. The variable x is the collection of coordinates and dx is the collection of differentials. For consistency, the indices here start from 0, ranging from $0 \sim n-1$. The results obtained are:
[[[0, 0], [0, -\sin(x0)\cdot \cos(x0)]], [[0, \cos(x0)/\sin(x0)], [\cos(x0)/\sin(x0), 0]]]
[[[[0, 0], [0, 0]], [[0, \sin(x0)\cdot \cdot 2], [-\sin(x0)\cdot \cdot 2, 0]]], [[[0, -1], [1, 0]], [[0, 0], [0, 0]]]]
As can be seen, the program lists all components. If we are only interested in non-zero components, we can use the following code for output:
for i1 in range(n):
for i2 in range(n):
for i3 in range(n):
if C[i1, i2, i3]:
print 'Gamma^%s_%s%s:'%(i1, i2, i3), C[i1, i2, i3]
for i1 in range(n):
for i2 in range(n):
for i3 in range(n):
for i4 in range(n):
if R[i1, i2, i3, i4]:
print 'Riemann^%s_%s%s%s:'%(i1, i2, i3, i4), R[i1, i2, i3, i4]
Obtaining:
Gamma^0_11: -\sin(x0)\cdot \cos(x0)
Gamma^1_01: \cos(x0)/\sin(x0)
Gamma^1_10: \cos(x0)/\sin(x0)
Riemann^0_101: \sin(x0)\cdot \cdot 2
Riemann^0_110: -\sin(x0)\cdot \cdot 2
Riemann^1_001: -1
Riemann^1_010: 1
Note that the curvature tensor calculated here is $R_{\alpha\beta\gamma}^{\mu}$. If the reader is interested in $R_{\mu\alpha\beta\gamma}$, and given that SymPy does not have a ready-made function for it, we can calculate it ourselves using the tensor operation library, i.e.,
from sympy.tensor.array import tensorproduct, tensorcontraction
tensorcontraction(tensorproduct(g, R), (1, 2))
where tensorproduct is used for the tensor product and tensorcontraction is used for contraction. Obtaining:
[[[[0, 0], [0, 0]], [[0, \sin(x0)\cdot \cdot 2], [-\sin(x0)\cdot \cdot 2, 0]]], [[[0, -\sin(x0)\cdot \cdot 2], [\sin(x0)\cdot \cdot 2, 0]], [[0, 0], [0, 0]]]]
Finally, if you want to output as LaTeX code, just use the latex command, for example:
for i1 in range(n):
for i2 in range(n):
for i3 in range(n):
if C[i1, i2, i3]:
print 'Gamma^%s_%s%s:'%(i1, i2, i3), \
latex(C[i1, i2, i3]).replace('\\mathrm{x_', '{x_').replace('\\boldsymbol{{x_', '{{x_')
The final replace is for minor adjustments, making the result more consistent with our usual notation. The result is:
Gamma^0_11: - \sin{\left ({{x_{0}}} \right )} \cos{\left ({{x_{0}}} \right )}
Gamma^1_01: \frac{\cos{\left ({{x_{0}}} \right )}}{\sin{\left ({{x_{0}}} \right )}}
Gamma^1_10: \frac{\cos{\left ({{x_{0}}} \right )}}{\sin{\left ({{x_{0}}} \right )}}
Lastly, we might need to calculate the curvature for a metric containing an undetermined function, such as $ds^2=f(x,y)(dx^2+dy^2)$. In this case, the code roughly looks like this:
f = Function('f')
g = [[f(x[0], x[1]), 0], [0, f(x[0], x[1])]]
metric = sum([g[i][j]*TP(dx[i], dx[j]) for i in range(n) for j in range(n)])
C = Christoffel(metric)
R = Riemann(metric)
At this point, terms like the following will appear in $\Gamma_{\alpha\beta}^{\mu}$:
Subs(Derivative(f(_xi_1, x1), _xi_1), (_xi_1,), (x0,))/(2\cdot f(x0, x1))
The conversion to LaTeX (with some simple processing as before to replace boldsymbol and mathrm tags) is:
$$\frac{\left. \frac{d}{d \xi_{1}} f{\left (\xi_{1},{{x_{1}}} \right )} \right|_{\substack{ \xi_{1}={{x_{0}}} }}}{2 f{\left ({{x_{0}}},{{x_{1}}} \right )}}$$
Which is actually:
$$\frac{ \frac{\partial }{\partial x_0} f\left (x_0, x_1 \right ) }{2 f{\left ({{x_{0}}},{{x_{1}}} \right )}}$$
Evidently, SymPy's output still has room for improvement; many places still require manual optimization. Even worse, terms like the following appear in $R_{\alpha\beta\gamma}^{\mu}$:
-Subs(Derivative(f(_#_1(_Dummy_38), x1), _#_1(_Dummy_38), _#_1(_Dummy_38)), (_#_1(_Dummy_38),), (x0,))/f(x0, x1) - Subs(Derivative(f(x0, _#_0(_Dummy_38)), _#_0(_Dummy_38), _#_0(_Dummy_38)), (_#_0(_Dummy_38),), (x1,))/f(x0, x1) + Subs(Derivative(f(_xi_1, x1), _xi_1), (_xi_1,), (x0,))\cdot \cdot 2/(2\cdot f(x0, x1)\cdot \cdot 2) + Subs(Derivative(f(x0, _xi_2), _xi_2), (_xi_2,), (x1,))\cdot \cdot 2/(2\cdot f(x0, x1)\cdot \cdot 2)
After LaTeX conversion, it is:
$$ - \frac{1}{f{\left ({{x_{0}}},{{x_{1}}} \right )}} \left. \frac{d^{2}}{d \operatorname{_#_{1}}{\left (Dummy_{38} \right )}^{2}} f{\left (\operatorname{_#_{1}}{\left (Dummy_{38} \right )},{{x_{1}}} \right )} \right|_{\substack{ \operatorname{_#_{1}}{\left (Dummy_{38} \right )}={{x_{0}}} }} - \frac{1}{f{\left ({{x_{0}}},{{x_{1}}} \right )}} \left. \frac{d^{2}}{d \operatorname{_#_{0}}{\left (Dummy_{38} \right )}^{2}} f{\left ({{x_{0}}},\operatorname{_#_{0}}{\left (Dummy_{38} \right )} \right )} \right|_{\substack{ \operatorname{_#_{0}}{\left (Dummy_{38} \right )}={{x_{1}}} }} + \frac{\left. \frac{d}{d \xi_{1}} f{\left (\xi_{1},{{x_{1}}} \right )} \right|_{\substack{ \xi_{1}={{x_{0}}} }}^{2}}{2 f^{2}{\left ({{x_{0}}},{{x_{1}}} \right )}} + \frac{\left. \frac{d}{d \xi_{2}} f{\left ({{x_{0}}},\xi_{2} \right )} \right|_{\substack{ \xi_{2}={{x_{1}}} }}^{2}}{2 f^{2}{\left ({{x_{0}}},{{x_{1}}} \right )}} $$
In fact, this will even cause an error! In this case, we also need to replace content such as \operatorname{_#_{0}}{\\left (Dummy_{38} \\right )} with ordinary symbols, for example:
print latex(R[0,1,0,1]).replace('\\mathrm{x_', '{x_').replace('\\boldsymbol{{x_', '{{x_')\
.replace('\\operatorname{_#_{0}}{\\left (Dummy_{38} \\right )}', '\\xi')\
.replace('\\operatorname{_#_{1}}{\\left (Dummy_{38} \\right )}', '\\xi')
Only then do we get a plausible output without errors:
$$ \begin{aligned} &- \frac{1}{f{\left ({{x_{0}}},{{x_{1}}} \right )}} \left. \frac{d^{2}}{d \xi^{2}} f{\left (\xi,{{x_{1}}} \right )} \right|_{\substack{ \xi={{x_{0}}} }} - \frac{1}{f{\left ({{x_{0}}},{{x_{1}}} \right )}} \left. \frac{d^{2}}{d \xi^{2}} f{\left ({{x_{0}}},\xi \right )} \right|_{\substack{ \xi={{x_{1}}} }} \\ &+ \frac{\left. \frac{d}{d \xi_{1}} f{\left (\xi_{1},{{x_{1}}} \right )} \right|_{\substack{ \xi_{1}={{x_{0}}} }}^{2}}{2 f^{2}{\left ({{x_{0}}},{{x_{1}}} \right )}} + \frac{\left. \frac{d}{d \xi_{2}} f{\left ({{x_{0}}},\xi_{2} \right )} \right|_{\substack{ \xi_{2}={{x_{1}}} }}^{2}}{2 f^{2}{\left ({{x_{0}}},{{x_{1}}} \right )}} \end{aligned} $$
Finally, this simplifies to:
$$-\frac{\frac{\partial^2 f(x_0, x_1)}{\partial x_0^2}}{f(x_0,x_1)} -\frac{\frac{\partial^2 f(x_0, x_1)}{\partial x_1^2}}{f(x_0,x_1)} + \frac{\left(\frac{\partial f(x_0, x_1)}{\partial x_0}\right)^2}{2f^2 (x_0,x_1)} + \frac{\left(\frac{\partial f(x_0, x_1)}{\partial x_1}\right)^2}{2f^2 (x_0,x_1)}$$
Or:
$$-\frac{\nabla^2 f}{f}+\frac{1}{2}\left|\frac{\nabla f}{f}\right|^2$$
Please include the address of this article when reposting: https://kexue.fm/archives/4026
If you find this article helpful, you are welcome to share / donate to this article. Donations are not intended for profit, but rather to know how much sincere attention "Scientific Space" has received from readers. Of course, if you ignore it, it will not affect your reading. Welcome and thank you once again!