#!/usr/bin/env python
# coding: utf-8
# # 13. Tensor fields
#
# 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()
# ### Linear differential forms (1- forms, covector fields) on a manifold
#
#
#
# Let $M$ be a smooth manifold.
# A **linear differential form or 1-form or covector field** $α$ on $M$ is a map that assigns to each $p ∈ M$ an element
# $α( p) ∈ T_p^∗M$ (the space $T_p^∗M$ was defined in [notebook 9](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/09Manifold_LinearFormsTensors_onTp.ipynb)) . The 1-form $α( p)$ will also be denoted by $α_p$, it is
# smooth (of class $C^∞$ ) if for all $X ∈ \mathfrak{X}(M)$ the function $α(X)$ defined by\begin{equation}
# (α(X))( p) = α_p (X_p ),\quad\text{for }\ p\in M
# \label{}\tag{13.1}
# \end{equation}
# is smooth (of class $C^∞$ ).
#
# The set of all smooth 1-forms on $M$ is denoted by $\Omega^1 (M)$. The
# set $\Omega^1(M)$ is a **module over** $C^∞ (M)$ with the algebraic operations given by
# \begin{equation}
# \begin{matrix}
# (α + β)_p ≡ α_p + β_p ,\\
# ( f α)_p ≡ f ( p)α_p ,
# \end{matrix}
# \label{}\tag{13.2}
# \end{equation}
# for $α, β ∈ \Omega^1 (M)$ and $f ∈ C^∞ (M).$
#
#
#
# **Example 13.1**
# Let us define a 1-form on a 3-dimensional manifold.
# In[2]:
get_ipython().run_line_magic('display', 'latex')
N = 3 # dimension of manifold M
M = Manifold(N, 'M') # manifold M
a = M.diff_form(1) # 1-form on M
a # print information on a
# In[3]:
# mathematical object of which "a" is an element.
a.parent()
#
#
# ### Differential of scalar functions
#
#
#
# If $f ∈ C^∞ (M)$, the **differential**
# of $f$ denoted by $d f$ is given by $$d f ( p) = d f_p,\quad\text{for}\ p\in M,$$ where $df_p$ is the differential at point defined in (9.1).
# The differential $df$ belongs to $\Omega^1(M).$ If $X ∈ \mathfrak{X}(M),$
# then from (13.1),(11.1),(9.1) it follows that
#
# $$(df(X))(p)=df_p(X_p)=X_p(f)=(Xf)(p),$$
# for $p ∈ M$ i.e.,
# \begin{equation}
# df(X)=X(f).
# \label{}\tag{13.3}
# \end{equation}
#
#
# **Example 13.2**
#
# Define a scalar function $f$ and its differential $df$. The differential is an example of 1-form.
# In[4]:
# continuation
f = M.scalar_field()
f.differential()
#
#
# ### The differential of function is a derivation
#
#
#
# The map $d : C^∞ (M) →\Omega^1 (M)$, which sends $f$ into $df$, satisfies
# \begin{equation}
# \begin{matrix}
# d(a f + bg) = ad f + bdg,\\
# d( f g) = f dg + gd f,
# \end{matrix}
# \label{}\tag{13.4}
# \end{equation}
# for $f, g ∈ C^∞ (M)$ and $a, b ∈ R.$
# To check the first equality note, that for $X\in \mathfrak{X}(M)$
#
# $$
# d(a f + bg)(X) = X(a f + bg) = aX f + bXg
# = a\,d f (X) + b\,dg(X) = (a\,d f + b\,dg)(X).
# $$
#
# The second one follows from
#
# $$
# d( f g)(X) = X( f g) = f Xg + gX f
# = f dg(X) + gd f (X) = ( f dg + gd f )(X).
# $$
#
#
# ### Differentials of coordinate functions form local bases for $\Omega^1(M)$
#
#
#
# If $(U, φ)$ is a chart on $M$, then as we have checked in [notebook 9](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/09Manifold_LinearFormsTensors_onTp.ipynb),
# the differentials of the
# coordinate functions $x^1 , x^2 , . . . , x^n$ computed at $p\in U$
# form the basis of $T_p^*M$.
# The formula (9.1') implies that on $U$ we have
# $$
# dx^i(X)=X(x^i).
# $$
#
# Since from (8.5) we have on $U$: $X=X(x^i)\frac{\partial}{\partial x^i},$ the covector field $dx^i$ assigns to the vector field $X$ its $i$-th component function $X(x^i)$ in the frame $\{\frac{\partial}{\partial x^j}\}_{j=1}^n$.
# If $α\in\Omega^1(M)$, using (9.2), we obtain for $p\in M$
# and $α(p) ∈ T_p^∗ (M)$
#
# $$\alpha(p)=\alpha(p)\big(\frac{\partial}{\partial x^i}\Big|_p\big)dx^i_p=\Big[\alpha\big(\frac{\partial}{\partial x^i}\big) dx^i\Big](p).$$
#
# Thus
#
# \begin{equation}
# \alpha=\alpha\big(\frac{\partial}{\partial x^i}\big) dx^i.
# \label{}\tag{13.5}
# \end{equation}
#
# If we denote $\alpha\big(\frac{\partial}{\partial x^i}\big)$ by $\alpha_i$ then in local coordinates every element of $\Omega^1(M)$ is of the form
#
# $$\alpha_idx^i.$$
#
# **Remark**. Let us underscore that the last expressions holds only locally (in the domain of a local chart).
#
#
#
# ### Coframe
#
#
#
# Recall that in [notebook 11](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/11Manifold_Vect_Fields.ipynb) we defined frames.
#
#
#
# If $U$ is an open subset of a manifold $M$ (for example a coordinate neighborhood) then the **coframe** on $U$ is the sequence $e$ of covector fields on $U$ such that for each $p∈U, \ e(p)$ is a basis of the cotangent space $T^*_pU$.
# From (13.5) it follows that the covectors $\ dx^1,\ldots,dx^n\ $ define a coframe on the coordinate neighborhood $U.\ $ Let us recall that the linear independence of $\ dx^1_p,\ldots,dx^n_p\ $ for every $p\in U$ was
# checked in [notebook 9](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/09Manifold_LinearFormsTensors_onTp.ipynb) (cf. the argument before the formula (9.2)).
#
# In[5]:
N = 3
M = Manifold(N, 'M') # manifold M
X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M
X
# In[6]:
X.coframe()[:]
#
# Using the local representation we can give concrete examples of 1-forms/covector fields.
#
#
#
# **Example 13.3**
#
# Define 1-form $\ a=a_0dx^0+a_1dx^1+a_2dx^2\ $ in SageMath.
# In[7]:
get_ipython().run_line_magic('display', 'latex')
N = 3 # dimension of manifold M
M = Manifold(N, 'M') # manifold M
X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M
a = M.diff_form(1,name='a') # 1-form a
ast = ['a'+str(j) for j in range(N)] # list of component names
af = [M.scalar_field(function(ast[j])(*X), name=ast[j])
for j in range(N)] # list of component functions
a[:] = af # define all components of a
a.disp() # show a
# Function arguments can be omitted:
# In[8]:
Manifold.options.omit_function_arguments=True
a.disp() # show abbreviated a
#
#
# **Example 13.4**
#
# Now use the local coordinates to show the differential of a scalar function.
# In[9]:
# continuation # scalar function f:
f = M.scalar_field(function('f')(*X), name='f')
df = f.differential() # differential of f
print(df) # show information on df
df.disp() # show df
# To explain the last formula let us note that by (13.5)
# $\ d f = d f (\frac{∂}{∂ x^i} )dx^i,\ $ but, by virtue of (13.3),
# $\ d f (\frac{\partial}{\partial x^i})= \frac{∂}{∂ x^i} f,\ $
# so that
# \begin{equation}
# d f = \frac{\partial f}{\partial x^i}dx^i.
# \label{}\tag{13.6}
# \end{equation}
# ## Tensor fields
#
#
# ### Tensor fields of type $\mathbf{(0,k)}$ (covariant tensor fields)
#
#
# A **tensor field $t$ of type $(0,k)$** or a **covariant tensor field of rank $k$** on a manifold $M$ is a map $t$ that associates with
# each point $p∈M$ a tensor $t(p)=t_p\in T^{(0,k)}_pM\ \ \ $ ($T^{(0,k)}_pM$ was defined in [notebook 9](09Manifold_LinearFormsTensors_onTp.ipynb)).
#
# If $t$
# is a tensor field of type $(0, k)$ and $X_1 , . . . , X_k$ are vector fields on $M$, then $t (X_1 , . . . , X_k)$ is the real-valued function given by
#
# $$[t (X_1 , . . . , X _k )]( p) = t_p (X_1 ( p), . . . , X_k ( p)).$$
#
# We say that $t$ is smooth if $t (X_1 , . . . , X_k )$ is a smooth function for all
# $X_1 , . . . , X_k ∈ \mathfrak{X}(M)$.
# One can prove that if $x^1,\ldots,x^n$ are local coordinates on $U$ and
# $t_{i_1\ldots i_k}=t(\frac{\partial}{\partial x^{i_1}},\ldots,\frac{\partial}{\partial x^{i_k}})$, then $t$ is smooth iff for arbitrary $p\in M$ there is a coordinate map
# $(U,(x^1,\ldots,x^n))$ around $p$ such that the real functions $t_{i_1\ldots i_k}$ are smooth.
# The operations of tensor addition, scalar multiplication and tensor product are defined pointwise:
#
# $$
# \begin{matrix}
# (at + bs)_p = at_p + bs_p,\\
# ( f t)_p = f ( p)t_p,\\
# (t ⊗ s)_p = t_p ⊗ s_p,
# \end{matrix}
# $$
#
# for $a, b ∈ R\ $, $s, t$ -covariant tensor fields on $M$ and $f : M → R.$
# Using these formulas and (9.5) we can check that arbitrary tensor field of type $(0,k)$ can be expressed in local coordinates as follows
#
# \begin{equation}
# \begin{matrix}
# t=t_{i_1\ldots i_k}dx^{i_1}\otimes\dots\otimes dx^{i_k},\\
# t_{i_1\ldots i_k}=t\big(\frac{\partial}{\partial x^{i_1}},\ldots,\frac{\partial}{\partial x^{i_k}}\big).
# \end{matrix}
# \tag{13.7}
# \end{equation}
#
#
# If $X_1 , . . . , X_k$ are vector fields on $M$ and $f\in C^\infty(M)$, then from the multi-linearity of $t_p$ on $T_pM$ for $p\in M$ it follows that
#
# $$[t (X_1 , . . . , f X_i , . . . , X_k )]( p) =
# t_p (X_1 ( p), . . . , ( f X_i )( p), . . . , X_k ( p))\\
# = t_p (X_1 ( p), . . . , f ( p)X_i ( p), . . . , X_k ( p))\\
# = f ( p)t_p( X_1 ( p), . . . , X_i ( p), . . . , X_k ( p))\\
# = f ( p)[t (X_1 , . . . , X_i , . . . , X_k )]( p),
# $$
#
# for $p ∈ M$. We have checked that
#
# $$t (X_1 , . . . , f X_i , . . . , X_k )=ft (X_1 , . . . , X_i , . . . , X_k ),\quad i=1,\ldots,k,$$
#
# for $X_i\in \mathfrak{X}(M)$ and $f\in C^\infty(M).$
#
# Similarly for $X_i,Y_i\in\mathfrak{X}(M)$ we can check that for $i=1,\ldots,k$
#
# $$t (X_1 , . . . , X_i + Y_i , . . . , X_k ) = t (X_1 , . . . , X_i , . . . , X_k ) + t (X_1 , . . . , Y_i , . . . , X_k ).$$
#
#
#
#
#
# ### Tensorial property
#
#
#
# If $t$ is a map that to each set of $k$ vector fields $X_i\in\mathfrak{X}(M)\ $ on $M$ associates a function $t(X_1,\ldots,X_k):M\to R$ with the property that for functions $f,g\in C^\infty(M),\ $ $X_i,Y_i\in\mathfrak{X}(M)\ $ and $i=1,\ldots,k$
#
# $$t (X_1 , . . . , fX_i + gY_i , . . . , X_k ) = ft (X_1 , . . . , X_i , . . . , X_k ) +gt (X_1 , . . . , Y_i , . . . , X_k ),$$
#
# then $t$ is a tensor field of type $(0,k).$
#
#
#
# Note that the last property means that covariant tensor fields of rank $k$ are just multilinear functions on the Cartesian product $\underbrace{\mathfrak{X}(M)\times\cdots\times \mathfrak{X}(M)}_{k\ \; \mbox{times}}$ of $k$ copies of the module $\mathfrak{X}(M)$ over the ring $C^\infty(M)$.
#
# The module of covariant tensor fields of type $(0,k)\ $ on a manifold $M$ will be denoted by $T^{(0,k)}M$.
#
# **Warning.** If $M$ is a module -not a manifold, in [notebook 9a](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/09aManifold_Tensors_onModules.ipynb) the same notations denote the space of covariant tensors of rank $k$ on the module $M$.
#
#
#
#
# ### Covariant tensor fields in components
#
#
#
# Using this property we can give another proof of (13.7). If the vector fields are expressed in the form $\quad X_i = dx^j (X_i ) \frac{∂}{∂ x^j} ,\quad i = 1, . . . , k,$ then
# $$t (X_1 , . . . , X_k ) = t(dx^i(X_1 )\frac{∂}{∂ x^i} , . . . ,
# dx^m (X_k )\frac{∂}{∂ x^m})\\
# = dx^i (X_1 ) · · · dx^m (X_k )\;t( \frac{∂}{∂ x^i},\ldots \frac{∂}{∂ x^m})\\
# =\Big[t(\frac{∂}{∂ x^i},\ldots \frac{∂}{∂ x^m})dx^i \otimes · · · \otimes dx^m\Big] (X_1 , . . . , X_k ).$$
#
#
#
# **Example 13.5**
#
# Define a general (0,2)-type tensor field on a 2-dimensional manifold (4 scalar functions as components).
# In[10]:
N = 2 # dimension of manifold
M = Manifold(N, 'M') # manifold M of dim. N
X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M
t = M.tensor_field(0, 2, name='t') # tensor field of type (0,2)
print(t) # show information on t
# The components of the tensor field $t$ are scalar functions
# In[11]:
x0, x1 = X[:] # coordinates x^0 and x^1 of chart X as the Python variables x0 and x1
f00 = M.scalar_field(function('f00')(x0, x1), name='f00') # scalar functions
f01 = M.scalar_field(function('f01')(x0, x1), name='f01') # defining components
f10 = M.scalar_field(function('f10')(x0, x1), name='f10')
f11 = M.scalar_field(function('f11')(x0, x1), name='f11')
t[0,0] = f00; t[0,1] = f01 # components of tensor field t
t[1,0] = f10; t[1,1] = f11
t.disp() # show t
# Let us check that $t_{ij}=t(\frac{\partial}{\partial x_i},\frac{\partial}{\partial x_j})$
# In[12]:
fr = X.frame();fr[:] # local frame on M
# In[13]:
matrix(2,2,lambda i,j: t(fr[i],fr[j]).expr()) # compute t(d/dxi,d/dxj)
# In[14]:
X.coframe()[:] # local coframe
#
#
# **Example 13.6**
#
# Let us define a more concrete example with variable components (upper indices and powers do not mix well).
# In[15]:
# continuation
t[:] = matrix(2, 2, lambda i,j: X[i]*X[j]) # t_{ij}=x_i*x_j
t.disp()
#
#
# **Example 13.7**
# An example of a (0,4)-type tensor field (`*` denotes the tensor product):
# In[16]:
(t*t).disp()
#
#
# **Example 13.8**
#
# Defining tensor fields with symbolic components we can use shorter and more general notation.
#
# Let us define a tensor field of type (0,2) in a more compact way.
# In[17]:
N = 2 # dimension of manifold M
M = Manifold(N, 'M') # manifold M
X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M
t = M.tensor_field(0,2, name='t') # tensor field of type (0,2)
def fn(i,j): return 'f'+str(i)+str(j) # names for components
def fl(i,j): return 'f'+'_'+'{'+str(i)+str(j)+'}' # latex comp.names
ff=[[M.scalar_field(function(fn(i,j),latex_name=fl(i,j))(*X))
for j in range(N)] for i in range(N)] # nested list of comp.
t[:] = ff # define all components
t.disp() # show the result
# As we can see, the result is the same as previously.
# The functions arguments can be omitted.
# In[18]:
Manifold.options.omit_function_arguments=True
t.disp()
# In[19]:
(t*t).disp()
# In[20]:
Manifold.options.omit_function_arguments=False
# **Remark**.
# If we want to make purely algebraic operations on tensor fields, then we can use symbols, not functions as components (this will not work if we want to use derivatives!).
#
#
# **Example 13.9**
#
# Define (0,3) type tensor field on a two dimensional manifold.
# In[21]:
N = 2 # dimension of manifold M
M = Manifold(N, 'M') # manifold M
X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M
t3 = M.tensor_field(0,3, name='t3')# tensor field of type (0,3)
print(t3) # information on t3
# We define a three-dimensional table of symbols $a_{ijk}$
# In[22]:
a3 =[[[SR('a'+str(i)+str(j)+str(k)) for k in range(N)]
for j in range(N)] for i in range(N)] # nested list of components
# and all components define with one equality.
# In[23]:
t3[:] = a3 # define all components as symbols
t3[:] # show components of t3
# In[24]:
t3.disp() # show the tensor
# Remember that the components in this example do not depend on coordinates.
#
#
# **Example 13.10**
#
# If we need a proper tensor field, with components depending on coordinates, the previous example should be modified.
#
# The first cell remains the same:
# In[25]:
N = 2 # dimension of manifold
M = Manifold(N, 'M') # manifold M
X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M
t3 = M.tensor_field(0,3, name='t3');print(t3) # tensor field
# but to define components we need scalar fields:
# In[26]:
def fn(i,j,k): return 'f'+str(i)+str(j)+str(k) # names of components
def fl(i,j,k): return 'f'+'_'+'{'+str(i)+str(j)+str(k)+'}' # latex names
# nested list of component functions
ff = [[[M.scalar_field(function(fn(i,j,k),latex_name=fl(i,j,k))(*X))
for k in range(N)] for j in range(N)] for i in range(N)]
t3[:] = ff # define all components
t3.disp() # show t3
# The functions argument can be omitted:
# In[27]:
Manifold.options.omit_function_arguments=True
t3.disp() # output without component arguments
# In[28]:
Manifold.options.omit_function_arguments=False
# Unfortunately, (in our system) latex encounters problems if the outputs are to long.
#
# If the latex formatted output is not needed, the `%display plain` method works properly.
# In[29]:
#(t3*t3).disp() returns latex code string
#(t3*t3)[:] works OK
Manifold.options.omit_function_arguments=True
tt = t3*t3
get_ipython().run_line_magic('display', 'plain')
tt.disp()
#
#
# ### Tensor fields of type $(k,0)$ (contravariant tensor fields of rank $k$)
#
#
#
# A **tensor field of type $(k, 0)$** (or a **contravariant tensor field
# of rank $k$**) on a manifold $M$ is a map $t$ that
# associates to each point $p ∈ M$ a tensor $t(p)=t_p\in T^{(k,0)}_pM\ \ \ $ ($T^{(k,0)}_pM$ was defined in [notebook 9](09Manifold_LinearFormsTensors_onTp.ipynb)).
#
# The tensor
# field $t$ is smooth if for arbitrary 1-forms $α_1 , . . . , α_k$ , the function $t(α_1 , . . . , α_k )$,
# defined by $[t (α_1, . . . , α_k )]( p) = t_p( α_1(p), . . . , α_k(p))$ , is smooth.
#
# The operations of tensor addition, scalar multiplication and tensor product are defined pointwise as in the case of covariant tensor fields.
#
#
#
# ### Tensorial property
#
#
#
# A map $t$ is a tensor field of type $(k,0)$ iff it associates to each set of $k$ covector fields $α_1 , . . . , α_k$ on $M$ a function $t(α_1 , . . . , α_k):M\to R$ with
# the property that for functions $f,g:M\to R$, $\alpha_1,\ldots,\alpha_k,\beta_1,\ldots,\beta_k\in T^*(M)$, and $i=1,\ldots,k$
#
# $$t (\alpha_1 , . . . , f\alpha_i + g\beta_i , . . . , \alpha_k ) = ft (\alpha_1 , . . . , \alpha_i , . . . , \alpha_k ) +gt (\alpha_1 , . . . , \beta_i , . . . , \alpha_k ).$$
#
#
#
# Note that the last property means that contravariant tensor fields of rank $k$ are just multilinear functions on the Cartesian product $\underbrace{\Omega^1(M)\times\cdots\times \Omega^1(M)}_{k\ \; \mbox{times}}$ of $k$ copies of the module $\Omega^1(M)$ over the ring $C^\infty(M)$.
#
# The module of contravariant tensor fields of type $(k,0)$
# on a manifold $M$ will be denoted by $T^{(𝑘,0)}M.$
#
#
# **Warning**. If $M$
# is a module -not a manifold, in [notebook 9a](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/09aManifold_Tensors_onModules.ipynb) the same notations denote the space of contravariant tensors of rank 𝑘 on the module $M$.
#
#
#
# ### Contravariant tensor fields in components
#
#
#
# Using (9.7) we can check that any tensor
# field of type $(k,0)$ on $M$ is expressed locally as
#
# \begin{equation}
# t = t (dx^{i_1} , . . . , dx^{i_k} )\frac{\partial}{\partial x^{i_1}}\otimes\dots\otimes
# \frac{\partial}{\partial x^{i_k}}.
# \label{}\tag{13.8}
# \end{equation}
#
# One can prove that if $x^1,\ldots,x^n$ are local coordinates on $U$ and
# $\ t^{i_1\ldots i_k}=t(dx^{i_1} , . . . , dx^{i_k} )\ $, then $t$ is smooth iff for arbitrary $p\in M$ there is a coordinate map
# $(U,(x^1,\ldots,x^n))$ around $p$ such that the real functions $\ t^{i_1\ldots i_k}\ $ are smooth.
#
#
# **Example 13.11**
#
# Let us show an example of tensor field $t\in T^{(2,0)}M$.
# In[30]:
get_ipython().run_line_magic('display', 'latex')
N = 2 # dimension of manifold M
M = Manifold(N, 'M') # manifold M
X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M
t = M.tensor_field(2,0, name='t'); print(t) # tensor field (2,0) type
# Below, we use superscripts to show that the contravariant tensor fields may look in SageMath Manifolds as in textbooks.
# In[31]:
def fn(i,j): return 'f'+str(i)+str(j) # component names
def fl(i,j): return 'f'+'^'+'{'+str(i)+str(j)+'}' # latex names
ff = [[M.scalar_field(function(fn(i,j),latex_name=fl(i,j))(*X))
for j in range(N)] for i in range(N)] # nested list of comp.
t[:] = ff # define all components
Manifold.options.omit_function_arguments=True # output without comp. arguments
t.disp() # show t
# Using tensor products it is easy to obtain large outputs.
# In[32]:
Manifold.options.omit_function_arguments=False # output with comp. arguments
(t*t).disp() # show tensor product
# In[33]:
Manifold.options.omit_function_arguments=True # output without comp. arguments
get_ipython().run_line_magic('display', 'plain')
(t*t).disp() # show tensor product
#
#
# **Example 13.12**
#
# The superscripts in contravariant tensor components are not obligatory.
# Let us modify the previous example using subscripts.
# In[34]:
reset()
N = 2 # dimension of manifold M
M = Manifold(N, 'M') # manifold M
X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M
t2 = M.tensor_field(2,0, name='t2') # tensor field (2,0) type
def hn(i,j): return 'h'+str(i)+str(j) # names for components
def hl(i,j): return 'h'+'_'+'{'+str(i)+str(j)+'}' # latex names
ff = [[M.scalar_field(function(hn(i,j), latex_name=hl(i,j))(*X))
for j in range(N)] for i in range(N)] # component functions
t2[:] = ff # define all components
Manifold.options.omit_function_arguments=True # output without comp.arg
get_ipython().run_line_magic('display', 'latex')
t2.disp() # show the tensor field
# In[35]:
tt2 = t2*t2
tt2.disp() # show tensor product
#
#
# **Example 13.13**
#
# Let us show an example of (3,0) type tensor field, using superscripts.
# In[36]:
get_ipython().run_line_magic('display', 'latex')
N = 2 # dimension of manifold M
M = Manifold(N, 'M') # manifold M
X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M
s3 = M.tensor_field(3,0, name='s3'); # tensor field of type (3,0)
# In[37]:
def fn(i,j,k): return 'f'+str(i)+str(j)+str(k) # components names
def fl(i,j,k): return 'f'+'^'+'{'+str(i)+str(j)+str(k)+'}' # latex names
ff = [[[M.scalar_field(function(fn(i,j,k),latex_name=fl(i,j,k))(*X))
for k in range(N)] for j in range(N)] for i in range(N)] # components
s3[:] = ff # define all components
Manifold.options.omit_function_arguments=True # output without comp. args
s3.disp() # show the tensor
# In[38]:
# check tensor product
ss3 = s3*s3
print(ss3)
#
#
# ### Tensor fields of type $(𝑘,m)$ (mixed tensor fields)
#
#
# A tensor field of type $(k,m)$ (a mixed tensor field) on $M$ is a map $t$
# that to each point $p ∈ M$ associates a tensor $t(p)=t_p\in T^{(k,m)}_pM\ \ \ $ ($T^{(k,m)}_pM$ was defined in [notebook 9](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/09Manifold_LinearFormsTensors_onTp.ipynb).
#
#
# A tensor field of type $(0,0)$ on $M$ is a scalar function $M\to R$.
#
# A tensor field
# $t$ of type $(k,m)$ is smooth if for $X_1 , . . . , X_m ∈ \mathfrak{X}(M)$ and $α_1 , . . . , α_k ∈ \Omega^1 (M)$,
# the function $M \to R$ that to each point $p ∈ M$ associates the value $t_p(α_1 ( p), . . . , α_k ( p),X_1 ( p), . . . , X_m ( p) )$ is smooth.
#
# The sum, the product by scalars, the product by real-valued functions, and the
# tensor product of mixed tensor fields are defined pointwise as in the case of covariant and contravariant tensors.
# $$
# \begin{matrix}
# (at + bs)_p = at_p + bs_p,\\
# ( f t)_p = f ( p)t_p,\\
# (t ⊗ s)_p = t_p ⊗ s_p,
# \end{matrix}
# $$
#
# for $a, b ∈ R$, $s, t$ mixed tensor fields on $M$ and $f : M → R$ (addition is defined only for tensors of the same type).
#
# The set of smooth
# tensor fields of type $(k,m)$ on a manifold $M$, will be denoted by $T^{(k,m)}M$.
# $T^{(k,m)}M$ **is a module over the ring $C^∞(M)$**.
#
# **Warning.** Recall, that in [notebook 9a](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/09aManifold_Tensors_onModules.ipynb), the same symbol $\ T^{(k,m)}M\ $ denotes the space of mixed tensors on a module $M$.
#
#
#
# ### Tensorial property
#
#
#
# As previously, we can check, that tensor fields of type $(k,m)$ are just multilinear functions on the Cartesian product
# $\underbrace{\Omega^1(M)\times\cdots\times \Omega^1(M)}_{k\ \; \mbox{times}}
# \times \underbrace{\mathfrak{X}(M)\times\cdots\times \mathfrak{X}(M)}_{m\ \; \mbox{times}}
# $ of $k$ copies of the module $\Omega^1(M)$ and $m$ copies of the module $\mathfrak{X}(M)$ over the ring $C^\infty(M)$.
#
#
#
# ### General tensor fields in components
#
#
#
# Generalizing the formulas (13.7) and (13.8) we obtain the following expression for the general tensor field $t\in T^{(k,m)}M$ in local components
#
# \begin{equation}
# t=
# t\big(dx^{i_1},..,dx^{i_k},\frac{\partial}{\partial x^{j_1}},..,\frac{\partial}{\partial x^{j_m}}\big)
# \frac{\partial}{\partial x^{i_1}}\otimes\dots\otimes\frac{\partial}{\partial x^{i_k}}\otimes dx^{j_1}\otimes\ldots\otimes dx^{j_m}.
# \label{}\tag{13.9}
# \end{equation}
#
# Very often the notation
# $$t^{i_1\ldots i_k}_{j_1\ldots j_m}=t\big(dx^{i_1},..,dx^{i_k},\frac{\partial}{\partial x^{j_1}},..,\frac{\partial}{\partial x^{j_m}}\big)
# $$
# is used and then
# $$t=t^{i_1\ldots i_k}_{j_1\ldots j_m}\frac{\partial}{\partial x^{i_1}}\otimes\dots\otimes\frac{\partial}{\partial x^{i_k}}\otimes dx^{j_1}\otimes\ldots\otimes dx^{j_m}.
# $$
# One can prove that if $x^1,\ldots,x^n$ are local coordinates on $U$ and $t^{i_1\ldots i_k}_{j_1\ldots j_m}$ are defined as above,
# then $t$ is smooth iff for arbitrary $p\in M$ there is a coordinate map
# $(U,(x^1,\ldots,x^n))$ around $p$ such that the real functions $t^{i_1\ldots i_k}_{j_1\ldots j_m}$ are smooth.
#
#
# **Example 13.14**
#
# Consider a 2-dimensional manifold with global coordinates $x^0,x^1$:
# In[39]:
get_ipython().run_line_magic('display', 'latex')
N = 2 # dimension of manifold M
M = Manifold(N, 'M') # manifold M
X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M
# Define a general tensor field of type (1,1).
#
# In the case of mixed type tensor fields it is important to distinguish the lower and upper indices!
# In[40]:
def fn(i,j): return 't'+str(i)+str(j) # component names
def fl(i,j): return 't'+'^'+str(i)+'_'+str(j) # latex names
ff = [[M.scalar_field(function(fn(i,j),latex_name=fl(i,j))(*X))
for j in range(N)] for i in range(N)] # list of components
t = M.tensor_field(1,1, name='t') # tensor of (1,1) type
t[:] = ff # define all components
t.disp() # show the tensor
# With this notations, the tensor product can be computed without problems:
# In[41]:
#t*t works
Manifold.options.omit_function_arguments=False # output with comp.args
tt = t*t # tensor product
tt.disp() # show tensor product
#
#
# **Example 13.15**
#
# Now let us try to define (2,2)-type tensor field on the same two-dimensional manifold
# In[42]:
# continuation; first define names and latex names of components
def fl(i0,i1,i2,i3): return 't'+'^'+'{'+str(i0)+str(i1)+'}'+'_'+'{'+str(i2)+str(i3)+'}'
def fn(i0,i1,i2,i3): return 't'+str(i0)+str(i1)+str(i2)+str(i3)
# define nested list of components of the tensor
ff = [[[[M.scalar_field(function(fn(i0,i1,i2,i3),latex_name=fl(i0,i1,i2,i3))(*X))
for i3 in range(N)] for i2 in range(N)] for i1 in range(N)] for i0 in range(N)]
t = M.tensor_field(2,2, name='t') # tensor field of type (2,2)
t[:] = ff # define all components#
Manifold.options.omit_function_arguments=True # output without comp. args
t.disp() # show the tensor
# Tensor product works with this notations (but the output is very long).
# In[43]:
#t*t works
tt = t*t
# In[44]:
# tt.disp() -latex code
# tt[:] very long output after very long time
# In[45]:
# %display plain
# tt.disp() # very-very long output
# It is easier to check that the linear operations work:
# In[46]:
Manifold.options.omit_function_arguments=True # output without comp.args
(t + 2*t).disp() # show t+2*t
# ## What's next?
#
# Take a look at the notebook [Differential k-forms](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/14Manifold_Differential_Forms.ipynb).