#!/usr/bin/env python
# coding: utf-8
# # 25. Torsion and curvature forms
#
# This notebook is part of the [Introduction to manifolds in SageMath](https://sagemanifolds.obspm.fr/intro_to_manifolds.html) by Andrzej Chrzeszczyk (Jan Kochanowski University of Kielce, Poland).
# In[1]:
version()
# To describe connections one can use bases not necessarily
# induced by coordinate systems. We can use sets $\{e_1 , . . . , e_n \}$ of smooth vector
# fields defined on some open subset $U$ of the manifold $M$ such that, at each point $p ∈ U $, the tangent vectors $e_i$ at $p$ form a basis of $T_p M$. Let the set of 1-forms $\{e^1 , . . . , e^n \}$ be its dual basis (i.e. $e^i (e_j ) = δ_{ij} $). If there exists a coordinate system $(x_1 , . . . , x_n )$ such
# that $e_i = \frac{∂}{∂ x^i}$ or, equivalently, $e^i = dx^i$ , we will say that the basis ${e_1 , . . . , e_n }$ is
# **holonomic**. In the present notebook the set $\{e_1,\ldots e_n\}$ will denote **not necessarily holonomic basis**.
#
#
# ### Connection forms
#
#
#
# If $∇$ is a connection on a manifold $ M$, the **connection forms**, $\omega^i_j$ , with
# respect to the basis $\{e_1 , . . . , e_n \}$, are the 1-forms defined by
#
# \begin{eqnarray}
# \omega_j^i(X)=e^i(\nabla_Xe_j),\quad \text{for} X\in \mathfrak{X}(M),
# \tag{25.1}
# \end{eqnarray}
# or equivalently
# \begin{eqnarray}
# \nabla_Xe_j=\omega_j^i(X)e_i,\quad \text{for} X\in \mathfrak{X}(M).
# \tag{25.1'}
# \end{eqnarray}
#
#
# **Example 25.1**
#
# On the two-dimensional manifold we have four connection forms $\omega^i_j$:
# In[2]:
get_ipython().run_line_magic('display', 'latex')
M = Manifold(2, 'M', start_index=1) # 2-dim. manifold M
c_xy. = M.chart() # chart on M
nab = M.affine_connection('nabla', r'\nabla') # affine connection
nab[1,1,1] = 0 # all con. coeff. zero
[nab.connection_form(i,j) for i in [1,2] for j in [1,2]]
#
#
# If we define
#
# \begin{eqnarray}
# \Gamma ^i_{jk}=\omega^i_j(e_k),
# \tag{25.2}
# \end{eqnarray}
#
# then for $X\in \mathfrak{X}(M)$, we have $X=e^k(X)e_k$ and
#
# $$
# \omega^i_j(X)=\omega^i_j(e^k(X)e_k)=e^k(X)\omega^i_j(e_k)=\Gamma^i_{jk}e^k(X),$$
#
# i.e.,
# \begin{eqnarray}
# \omega_j^i=\Gamma^i_{jk}e^k,
# \tag{25.3}
# \end{eqnarray}
# and according to (25.1')
#
# \begin{eqnarray}
# \nabla_{e_i}e_j=\omega_j^k(e_i)e_k=\Gamma^k_{ji}e_k,
# \tag{25.4}
# \end{eqnarray}
#
# which is analogous to (21.5) but holds also for non-holonomic bases.
#
#
# ### Torsion forms
#
#
#
# If $T (X, Y) = ∇ X Y − ∇ Y X − [X, Y],\ \ X, Y ∈ \mathfrak{X}(M)\ \ $ is the torsion, then the **torsion 2-forms** $\theta^i$ with respect to $\{e_1,\ldots,e_n\}$ are defined by
#
# \begin{eqnarray}
# \theta^i(X,Y)=e^i(T(X,Y)),\quad \text{for}\ X,Y\in \mathfrak{X}(M),
# \tag{25.5}
# \end{eqnarray}
# or equivalently
#
# \begin{eqnarray}
# T(X,Y)=\theta^i(X,Y)e_i,\quad \text{for}\ X,Y\in \mathfrak{X}(M).
# \tag{25.6}
# \end{eqnarray}
#
# Since $T$ is antisymmetric, each $\theta^i$ is 2-form.
#
#
#
# **Example 25.2**
#
# On the two-dimensional manifold we have two torsion 2-forms:
# In[3]:
get_ipython().run_line_magic('display', 'latex')
M = Manifold(2, 'M', start_index=1) # 2-dim. manifold M
c_xy. = M.chart() # chart on M
nab = M.affine_connection('nabla', r'\nabla') # affine connection
nab[1,1,1] = 0 # all con. coeff. zero
[nab.torsion_form(i) for i in [1,2]] # torsion 2-forms on M
#
#
# ### First Cartan structure equation
#
#
#
# Assume we have vector fields $\ X\ $ and $\ Y=Y^ie_i=e^i(Y)e_i.\ $ From (21.14) it follows
#
# \begin{equation}
# \nabla_Xt(Y)=X(t(Y))-t(\nabla_XY),
# \tag{*}
# \end{equation}
#
# for 1-forms $t$ on $M$, so
#
# $$\nabla_Xe^i(Y)=X(e^i(Y))-e^i(\nabla_XY)
# =X(Y^i)-e^i(\nabla_X(Y^je_j))\\
# =X(Y^i)-e^i(Y^j\nabla_Xe_j+(XY^j)e_j)\\
# =X(Y^i)-Y^je^i(\nabla_Xe_j)-e^i((XY^j)e_j)\\
# =X(Y^i)-Y^je^i(\nabla_Xe_j)-X(Y^i)\\
# =-Y^j\omega^i_j(X)=-\omega^i_j(X)e^j(Y),
# $$
# so
# \begin{eqnarray}
# \nabla_Xe^i=-\omega^i_j(X)e^j.
# \tag{25.7}
# \end{eqnarray}
# Using (*) once again we obtain
#
# $$
# e^i(\nabla_XY)=X(e^i(Y))-(\nabla_Xe^i)(Y),\\
# e^i(\nabla_YX)=Y(e^i(X))-(\nabla_Ye^i)(X).
# $$
#
# From (16.6) we know that
#
# $$
# (d\omega)(X,Y)=X\omega(Y)-Y\omega(X)-\omega([X,Y]),
# $$
#
# and from the definition of the exterior product
#
# $$
# t\wedge s=t\otimes s-s\otimes t.
# $$
#
# From those facts
# and (25.7) we obtain
#
# $$\theta^i(X,Y)=e^i(T(X,Y))=e^i(\nabla_XY-\nabla_YX-[X,Y])\\
# =X(e^i(Y))-(\nabla_Xe^i)(Y)-Y(e^i(X))+(\nabla_Ye^i)(X)-e^i([X,Y])\\
# =X(e^i(Y))-Y(e^i(X)-e^i([X,Y])-(\nabla_Xe^i)(Y)+(\nabla_Ye^i)(X)\\
# =de^i(X,Y)+\omega^i_j(X)e^j(Y)-\omega^i_j(Y)e^j(X)\\
# =(de^i+\omega^i_j\wedge e^j)(X,Y).
# $$
#
# We have proved **the first Cartan structural equation**
#
# \begin{eqnarray}
# \theta^i=de^i+\omega^i_j\wedge e^j.
# \tag{25.8}
# \end{eqnarray}
#
#
# ### Curvature forms
#
#
# If $\ \ R(X, Y)= ∇_X ∇_Y − ∇_Y ∇_X − ∇_{[X,Y]},\ \
# X, Y ∈ \mathfrak{X}(M)\ \ $ is the curvature, then the **curvature forms** $\Omega^i_j(X,Y)$ with respect to the basis $\{e_1 , e_2 , . . . , e_n \}$, are defined by
#
# \begin{equation}
# \Omega^i_j(X,Y)=e^i(R(X,Y)e_j),\quad X, Y ∈ \mathfrak{X}(M),
# \tag{25.9}
# \end{equation}
#
# or equivalently
#
# \begin{equation}
# R(X,Y)e_j=\Omega^i_j(X,Y)e_i,\quad X, Y ∈ \mathfrak{X}(M).
# \tag{25.9'}
# \end{equation}
#
#
#
# **Example 25.3**
#
# On the two-dimensional manifold we have four curvature forms:
# In[4]:
get_ipython().run_line_magic('display', 'latex')
M = Manifold(2,'M',start_index=1) # manifold M
c_xy. = M.chart() # chart on M
nab = M.affine_connection('nabla', r'\nabla') # connection
nab[1,1,1] = 0 # all coefficients zero
[nab.curvature_form(i,j) for i in [1,2] for j in [1,2]]
# curvature forms
#
#
# ### Second Cartan structural equations
#
#
#
# If we use the formulas
# $$ R(X, Y)= ∇_X ∇_Y − ∇_Y ∇_X − ∇_{[X,Y]},\\
# \nabla_Xe_j=\omega^i_j(X)e_i,\quad \omega^i_j(X)=e^i(\nabla_Xe_j),\\
# \nabla_X(\omega^k_j(Y)e_k)=X(\omega^k_j(Y))e_k+\omega^k_j(Y)\nabla_Xe_k,\\
# (d\omega)(X,Y)=X\omega(Y)-Y\omega(X)-\omega([X,Y]),\\
# t\wedge s=t\otimes s-s\otimes t,
# $$
# then we can check that
# $$\Omega^i_j(X,Y)=e^i(∇_X ∇_Y e_j − ∇_Y ∇_X e_j− ∇_{[X,Y]}e_j)\\
# =e^i(\nabla_X(\omega^k_j(Y)e_k)-\nabla_Y(\omega^k_j(X)e_k))-\omega^i_j([X,Y])\\
# =e^i(X(\omega^k_j(Y))e_k+\omega^k_j(Y)\nabla_Xe_k-Y(\omega^k_j(X))e_k-\omega^k_j(X)\nabla_Ye_k)-\omega^i_j([X,Y])\\
# =(X(\omega^k_j(Y))e^i(e_k)+\omega_j^k(Y)e^i(\nabla_Xe_k)\\
# -Y(\omega^k_j(X))e^i(e_k)-\omega^k_j(X)e^i(\nabla_Ye_k))-
# \omega^i_j([X,Y])\\
# =X(\omega^i_j(Y))+\omega_j^k(Y)\omega^i_k(X)-Y(\omega^i_j(X))-\omega^k_j(X)\omega^i_k(Y)-\omega^i_j([X,Y])\\
# =X(\omega^i_j(Y))-Y(\omega^i_j(X))-\omega^i_j([X,Y])+\omega_k^i(X)\omega^k_j(Y)-\omega^i_k(Y)\omega_j^k(X)\\
# =d\omega^i_j(X,Y)+(\omega^i_k\wedge \omega^k_j)(X,Y).
# $$
#
# We have proved **the second Cartan structural equation**
#
# \begin{equation}
# \Omega^i_j=d\omega^i_j+\omega^i_k\wedge \omega^k_j.
# \tag{25.10}
# \end{equation}
#
#
# **Observation:** $\hskip0.5cm$ If $A_{kl}$ is an antisymmetric matrix, then for 1-forms $e^i$ on $M$ and $X,Y\in\mathfrak{X}(M)$
# $$(A_{kl}e^k\wedge e^l)(X,Y)=A_{kl}(e^k\otimes e^l-e^l\otimes e^k)(X,Y)\\
# =A_{kl}(e^k(X) e^l(Y)-e^l(X) e^k(Y)
# =A_{kl}X^kY^l-A_{kl}X^lY^k\\
# =A_{kl}X^kY^l+A_{lk}X^lY^k
# =2A_{kl}X^kY^l.
# $$
#
#
# If the components of the torsion and the curvature tensors with respect to the basis $\{e_1 , . . . , e_n \}$ are defined by
# $$T (e_i , e_j ) = T^k_{i j} e_k,\quad R(e_i , e_j )e_k = R^l_{ki j}e_l,
# $$
# then
# \begin{equation}
# \begin{matrix}
# \theta^i=\frac{1}{2}T^i_{jk}e^j\wedge e^k,\\
# \Omega^i_j=\frac{1}{2}R^i_{jkl}e^k\wedge e^l.
# \end{matrix}
# \tag{25.11}
# \end{equation}
# In fact
# $$\theta^i(X,Y)=e^i(T(X,Y))=e^i(T(X^ke_k,Y^le_l))\\
# =e^i(X^kY^lT^m(e_k,e_l)e_m)=e^i(X^kY^lT^m_{kl}e_m)\\
# =X^kY^lT^m_{kl}e^l(e_m)=X^kY^lT^m_{kl}\delta^i_m=X^kY^lT^i_{kl}\\
# =\frac{1}{2}(T^i_{kl}e^k\wedge e^l)(X,Y),
# $$
# and
# $$
# \Omega^i_j(X,Y)=e^i(R(X,Y)e_j)=e^i(R(X^ke_k,Y^le_l)e_j)\\
# =X^kY^lR^m_{jkl}e^i(e_m)=X^kY^lR^m_{jkl}\delta^i_m\\
# =X^kY^lR^i_{jkl}=\frac{1}{2}(R^i_{jkl}e^k\wedge e^l)(X,Y).
# $$
#
#
#
# **Example 25.4**
#
# Consider the half-plane $y>0$ with the connection coefficients with respect to the bases $\ \ e_1=\frac{\partial}{\partial x},\ \ e_2=\frac{\partial}{\partial y},\ \ e^1=dx,\ \ e^2=dy\ \ $ equal to
# $$\Gamma^1_{12}=\Gamma^1_{21}=\Gamma^2_{22}=-\frac{1}{y}, \quad\Gamma^2_{11}=\frac{1}{y},$$
# and all other coefficients equal to zero.
# In[5]:
get_ipython().run_line_magic('display', 'latex')
M = Manifold(2, 'M', start_index=1) # manifold M
c_xy. = M.chart() # chart on M
nab = M.affine_connection('nabla', r'\nabla') # connection on M
# con. coefficients
nab[1,1,2], nab[1,2,1], nab[2,2,2], nab[2,1,1] = -1/y, -1/y, -1/y, 1/y
nab.display(coordinate_labels=False) # show conn. coeff.
# (only nonzero)
# Connection forms $\omega^i_j$ can be computed using the formula
# (25.3), $\ \ \omega_j^i=\Gamma^i_{jk}e^k$:
# $$\omega^1_1=\Gamma^1_{11}e^1+\Gamma^1_{12}e^2=-\frac{1}{y}dy,\\
# \omega^1_2=\Gamma^1_{21}e^1+\Gamma^1_{22}e^2=-\frac{1}{y}dx,\\
# \omega^2_1=\Gamma^2_{11}e^1+\Gamma^2_{12}e^2=\frac{1}{y}dx,\\
# \omega^2_2=\Gamma^2_{21}e^1+\Gamma^2_{22}e^2=-\frac{1}{y}dy.
# $$
# In[6]:
[nab.connection_form(i,j).display() # connection forms
for i in [1,2] for j in [1,2]]
#
#
# Torsion forms can be computed from the first Cartan structure equation (25.8), $\ \ \theta^i=de^i+\omega^i_j\wedge e^j$:
#
# $$\theta^1=de^1+\omega^1_1\wedge e^1+\omega^1_2\wedge e^2
# =d(dx)-\frac{1}{y}dy\wedge dx-\frac{1}{y}dx\wedge dy=0,\\
# \theta^2=de^2+\omega^2_1\wedge e^1+\omega^2_2\wedge e^2
# =d(dy)+\frac{1}{y}dx\wedge dx-\frac{1}{y}dy\wedge dy=0.\\
# $$
# In[7]:
[nab.torsion_form(i).disp() for i in [1,2]] # torsion forms
# The second Cartan structure equation (25.10):
# $\ \Omega^i_j=d\omega^i_j+\omega^i_k\wedge \omega^k_j$
# can be used in calculation of curvature forms:
#
# $$
# \Omega_1^1=d\omega^1_1+\omega^1_1\wedge \omega^1_1+\omega^1_2\wedge \omega^2_1\\=d\Big(-\frac{1}{y}dy\Big)-\Big(\frac{1}{y}dx\Big)\wedge \Big(\frac{1}{y}dx\Big)\\
# =\frac{1}{y^2}dy\wedge dy=0,$$
#
#
#
# $$
# \Omega^1_2=d\omega^1_2+\omega^1_1\wedge \omega^1_2+\omega^1_2\wedge \omega^2_2\\
# =d\Big(-\frac{1}{y}dx\Big)
# +\Big(-\frac{1}{y}dy\Big)\wedge \Big(-\frac{1}{y}dx\Big)
# +\Big(-\frac{1}{y}dx\Big)\wedge \Big(-\frac{1}{y}dy\Big)\\
# =\frac{1}{y^2}dy\wedge dx+\frac{1}{y^2}dy\wedge dx+\frac{1}{y^2}dx\wedge dy=-\frac{1}{y^2}dx\wedge dy,$$
#
#
# $$
# \Omega^2_1=d\omega^2_1+\omega^2_1\wedge \omega^1_1+\omega^2_2\wedge \omega^2_1\\
# =d\Big(-\frac{1}{y}dx\Big)
# +\Big(\frac{1}{y}dx\Big)\wedge \Big(-\frac{1}{y}dy\Big)
# +\Big(-\frac{1}{y}dy\Big)\wedge \Big(\frac{1}{y}dx\Big)\\
# =\frac{1}{y^2}dy\wedge dx-\frac{1}{y^2}dx\wedge dy-\frac{1}{y^2}dy\wedge dx=\frac{1}{y^2}dx\wedge dy,
# $$
#
#
# $$
# \Omega^2_2=d\omega^2_2+\omega^2_1\wedge \omega^1_2+\omega^2_2\wedge \omega^2_2\\
# =d\Big(-\frac{1}{y}dy\Big)+
# \Big(\frac{1}{y}dx\Big)\wedge \Big(-\frac{1}{y}dx\Big)\\
# =\frac{1}{y^2}dy\wedge dy-\frac{1}{y^2}dx\wedge dx=0.
# $$
# In[8]:
[nab.curvature_form(i,j).display() # curvature forms
for i in [1,2] for j in [1,2]]
#
#
# Since by (25.11) $\quad \Omega^i_j=\frac{1}{2}R^i_{jkl}e^k\wedge e^l$, and $R^i_{jkl}$ is antisymmetric in $k,l$, then
# $$\Omega_2^1=\frac{1}{2}R^1_{2kl}e^k\wedge e^l=
# \frac{1}{2}(R^1_{212}dx\wedge dy+R^1_{221}dy\wedge dx)\\
# =\frac{1}{2}(R^1_{212}dx\wedge dy+R^1_{212}dx\wedge dy)=R^1_{212}dx\wedge dy=-\frac{1}{y^2}dx\wedge dy,
# $$
#
# Using an analogous calculation for $\Omega^2_1$, we see that the different from zero components
# of the curvature tensor are equal to:
#
# $R^1_{212} =-\frac{1}{y^2},\ \
# R^1_{221} =\frac{1}{y^2},\ \ R^2_{112}=\frac{1}{y^2},\ \ R^2_{121}=-\frac{1}{y^2}$.
# In[9]:
R = M.tensor_field(1,3,'R') # tensor field of (1,3)-type
R[:] = nab.riemann()[:] # R <- curv. (1,3) tensor f.
R.display_comp(coordinate_labels=False) # show R
#nab.riemann().display_comp(coordinate_labels=False)
#
#
# **Example 25.5**
#
# Consider the plane $R^2$ with Christoffel symbols
# $$Γ^1_{11}= Γ^1_{22}=\frac{4u}{1+u^2+4v^2},\\
# Γ^2_{11}= Γ^2_{22}=\frac{4v}{1+u^2+4v^2},
# $$
# and the remaining symbols equal to 0.
# In[10]:
get_ipython().run_line_magic('display', 'latex')
N = Manifold(2,name='R2',start_index=1) # manifold N
c_uv. = N.chart() # chart on N
nab = N.affine_connection('nab1') # connection coefficients
nab[:] = [[[4*u/(4*u^2 + 4*v^2 + 1), 0], # define all coefficients
[0, 4*u/(4*u^2 + 4*v^2 + 1)]],
[[4*v/(4*u^2 + 4*v^2 + 1), 0],
[0, 4*v/(4*u^2 + 4*v^2 + 1)]]]
# Compute connection forms:
# In[11]:
[nab.connection_form(i,j).display() # connection forms
for i in [1,2] for j in [1,2]]
# and torsion forms:
# In[12]:
[nab.torsion_form(i).disp() # torsion forms
for i in [1,2]]
# Now let us try to compute curvature forms.
# In[13]:
[nab.curvature_form(i,j) # curvature forms -symbols
for i in [1,2] for j in [1,2]]
# Before we show the results, we have to do some simplifications.
# In[14]:
for i in [1,2]: # factor curvature forms
for j in [1,2]:
nab.curvature_form(i,j).comp()[:].apply_map(factor)
# In[15]:
for i in [1,2]: # show curvature forms
for j in [1,2]:
show(nab.curvature_form(i,j).disp())
# ###
#
# **Example 25.6**
#
# In previous examples, the torsion forms were equal to zero.
#
# Let us consider a 2-dimensional manifold with "random" connection coefficients.
# In[16]:
M = Manifold(2, 'M', start_index=1) # manifold M
c_xy. = M.chart() # chart on M
nab = M.affine_connection('nabla', r'\nabla') # connection on M
nab[1,1,1], nab[1,1,2] = x*y, x^2
nab[1,2,1], nab[1,2,2] = -x^3, y^2
nab[2,1,1], nab[2,1,2] = y^2, x*y
nab[2,2,1], nab[2,2,2] = x^2+y^2+y^2, y^2-x^2
# In[17]:
get_ipython().run_line_magic('display', 'latex # show connection')
nab[:] # coefficients
# Compute the connection forms:
# In[18]:
[[nab.connection_form(i,j).display() # connection forms
for j in [1,2]] for i in [1,2]]
# Recall that the torsion was defined in (21.13) as
#
# $$T (X, Y) = ∇_X Y − ∇_Y X − [X, Y],\quad \text{for}\quad X,Y\in \mathfrak{X}(M).$$
#
# In SageMath the `torsion` method returns the tensor of type (1,2) defined by
#
# $$\tilde{T}(\omega,X,Y)=\omega(T(X,Y)),\quad \text{for}\quad X,Y\in \mathfrak{X}(M), \omega\in \Omega^1(M).
# $$
# In[19]:
print(nab.torsion()) # torsion (1,2) tensor
nab.torsion().disp()
# The torsion forms in our example are equal to:
# In[20]:
for i in [1,2]: # torsion forms
show(nab.torsion_form(i).disp())
# and the curvature forms:
# In[21]:
for i in [1,2]: # curvature forms
for j in [1,2]:
show(nab.curvature_form(i,j).disp())