Differential Forms¶
Let \(U\) and \(M\) be two differentiable manifolds. Given a positive integer \(p\) and a differentiable map \(\Phi: U \rightarrow M\), a differential form of degree \(p\), or \(p\)-form, along \(U\) with values on \(M\) is a field along \(U\) of alternating multilinear forms of degree \(p\) in the tangent spaces to \(M\). The standard case of a differential form on a differentiable manifold corresponds to \(U = M\) and \(\Phi = \mathrm{Id}_M\). Other common cases are \(\Phi\) being an immersion and \(\Phi\) being a curve in \(M\) (\(U\) is then an open interval of \(\RR\)).
Two classes implement differential forms, depending whether the manifold \(M\) is parallelizable:
DiffFormParal
when \(M\) is parallelizableDiffForm
when \(M\) is not assumed parallelizable.
AUTHORS:
Eric Gourgoulhon, Michal Bejger (2013, 2014): initial version
Joris Vankerschaver (2010): developed a previous class,
DifferentialForm
(cf. Issue #24444), which inspired the storage of the nonzero components as a dictionary whose keys are the indices.Travis Scrimshaw (2016): review tweaks
REFERENCES:
- class sage.manifolds.differentiable.diff_form.DiffForm(vector_field_module, degree, name=None, latex_name=None)[source]¶
Bases:
TensorField
Differential form with values on a generic (i.e. a priori not parallelizable) differentiable manifold.
Given a differentiable manifold \(U\), a differentiable map \(\Phi: U \rightarrow M\) to a differentiable manifold \(M\) and a positive integer \(p\), a differential form of degree \(p\) (or \(p\)-form) along \(U\) with values on \(M\supset\Phi(U)\) is a differentiable map
\[a:\ U \longrightarrow T^{(0,p)}M\](\(T^{(0,p)}M\) being the tensor bundle of type \((0,p)\) over \(M\)) such that
\[\forall x \in U,\quad a(x) \in \Lambda^p(T_{\Phi(x)}^* M) ,\]where \(T_{\Phi(x)}^* M\) is the dual of the tangent space to \(M\) at \(\Phi(x)\) and \(\Lambda^p\) stands for the exterior power of degree \(p\) (cf.
ExtPowerDualFreeModule
). In other words, \(a(x)\) is an alternating multilinear form of degree \(p\) of the tangent vector space \(T_{\Phi(x)} M\).The standard case of a differential form on a manifold \(M\) corresponds to \(U = M\) and \(\Phi = \mathrm{Id}_M\). Other common cases are \(\Phi\) being an immersion and \(\Phi\) being a curve in \(M\) (\(U\) is then an open interval of \(\RR\)).
Note
If \(M\) is parallelizable, the class
DiffFormParal
must be used instead.INPUT:
vector_field_module
– module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(M\) via the map \(\Phi\)degree
– the degree of the differential form (i.e. its tensor rank)name
– (default:None
) name given to the differential formlatex_name
– (default:None
) LaTeX symbol to denote the differential form; if none is provided, the LaTeX symbol is set toname
EXAMPLES:
Differential form of degree 2 on a non-parallelizable 2-dimensional manifold:
sage: M = Manifold(2, 'M') sage: U = M.open_subset('U') ; V = M.open_subset('V') sage: M.declare_union(U,V) # M is the union of U and V sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart() sage: xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W', ....: restrictions1= x>0, restrictions2= u+v>0) sage: uv_to_xy = xy_to_uv.inverse() sage: W = U.intersection(V) sage: eU = c_xy.frame() ; eV = c_uv.frame() sage: a = M.diff_form(2, name='a') ; a 2-form a on the 2-dimensional differentiable manifold M sage: a.parent() Module Omega^2(M) of 2-forms on the 2-dimensional differentiable manifold M sage: a.degree() 2
>>> from sage.all import * >>> M = Manifold(Integer(2), 'M') >>> U = M.open_subset('U') ; V = M.open_subset('V') >>> M.declare_union(U,V) # M is the union of U and V >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2); c_uv = V.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2) >>> xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W', ... restrictions1= x>Integer(0), restrictions2= u+v>Integer(0)) >>> uv_to_xy = xy_to_uv.inverse() >>> W = U.intersection(V) >>> eU = c_xy.frame() ; eV = c_uv.frame() >>> a = M.diff_form(Integer(2), name='a') ; a 2-form a on the 2-dimensional differentiable manifold M >>> a.parent() Module Omega^2(M) of 2-forms on the 2-dimensional differentiable manifold M >>> a.degree() 2
Setting the components of
a
:sage: a[eU,0,1] = x*y^2 + 2*x sage: a.add_comp_by_continuation(eV, W, c_uv) sage: a.display(eU) a = (x*y^2 + 2*x) dx∧dy sage: a.display(eV) a = (-1/16*u^3 + 1/16*u*v^2 - 1/16*v^3 + 1/16*(u^2 - 8)*v - 1/2*u) du∧dv
>>> from sage.all import * >>> a[eU,Integer(0),Integer(1)] = x*y**Integer(2) + Integer(2)*x >>> a.add_comp_by_continuation(eV, W, c_uv) >>> a.display(eU) a = (x*y^2 + 2*x) dx∧dy >>> a.display(eV) a = (-1/16*u^3 + 1/16*u*v^2 - 1/16*v^3 + 1/16*(u^2 - 8)*v - 1/2*u) du∧dv
A 1-form on
M
:sage: a = M.one_form(name='a') ; a 1-form a on the 2-dimensional differentiable manifold M sage: a.parent() Module Omega^1(M) of 1-forms on the 2-dimensional differentiable manifold M sage: a.degree() 1
>>> from sage.all import * >>> a = M.one_form(name='a') ; a 1-form a on the 2-dimensional differentiable manifold M >>> a.parent() Module Omega^1(M) of 1-forms on the 2-dimensional differentiable manifold M >>> a.degree() 1
Setting the components of the 1-form in a consistent way:
sage: a[eU,:] = [-y, x] sage: a.add_comp_by_continuation(eV, W, c_uv) sage: a.display(eU) a = -y dx + x dy sage: a.display(eV) a = 1/2*v du - 1/2*u dv
>>> from sage.all import * >>> a[eU,:] = [-y, x] >>> a.add_comp_by_continuation(eV, W, c_uv) >>> a.display(eU) a = -y dx + x dy >>> a.display(eV) a = 1/2*v du - 1/2*u dv
It is also possible to set the components at the 1-form definition, via a dictionary whose keys are the vector frames:
sage: a1 = M.one_form({eU: [-y, x], eV: [v/2, -u/2]}, name='a') sage: a1 == a True
>>> from sage.all import * >>> a1 = M.one_form({eU: [-y, x], eV: [v/Integer(2), -u/Integer(2)]}, name='a') >>> a1 == a True
The exterior derivative of the 1-form is a 2-form:
sage: da = a.exterior_derivative() ; da 2-form da on the 2-dimensional differentiable manifold M sage: da.display(eU) da = 2 dx∧dy sage: da.display(eV) da = -du∧dv
>>> from sage.all import * >>> da = a.exterior_derivative() ; da 2-form da on the 2-dimensional differentiable manifold M >>> da.display(eU) da = 2 dx∧dy >>> da.display(eV) da = -du∧dv
The exterior derivative can also be obtained by applying the function
diff
to a differentiable form:sage: diff(a) is a.exterior_derivative() True
>>> from sage.all import * >>> diff(a) is a.exterior_derivative() True
Another 1-form defined by its components in
eU
:sage: b = M.one_form(1+x*y, x^2, frame=eU, name='b')
>>> from sage.all import * >>> b = M.one_form(Integer(1)+x*y, x**Integer(2), frame=eU, name='b')
Since
eU
is the default vector frame onM
, it can be omitted in the definition:sage: b = M.one_form(1+x*y, x^2, name='b') sage: b.add_comp_by_continuation(eV, W, c_uv)
>>> from sage.all import * >>> b = M.one_form(Integer(1)+x*y, x**Integer(2), name='b') >>> b.add_comp_by_continuation(eV, W, c_uv)
Adding two 1-forms results in another 1-form:
sage: s = a + b ; s 1-form a+b on the 2-dimensional differentiable manifold M sage: s.display(eU) a+b = ((x - 1)*y + 1) dx + (x^2 + x) dy sage: s.display(eV) a+b = (1/4*u^2 + 1/4*(u + 2)*v + 1/2) du + (-1/4*u*v - 1/4*v^2 - 1/2*u + 1/2) dv
>>> from sage.all import * >>> s = a + b ; s 1-form a+b on the 2-dimensional differentiable manifold M >>> s.display(eU) a+b = ((x - 1)*y + 1) dx + (x^2 + x) dy >>> s.display(eV) a+b = (1/4*u^2 + 1/4*(u + 2)*v + 1/2) du + (-1/4*u*v - 1/4*v^2 - 1/2*u + 1/2) dv
The exterior product of two 1-forms is a 2-form:
sage: s = a.wedge(b) ; s 2-form a∧b on the 2-dimensional differentiable manifold M sage: s.display(eU) a∧b = (-2*x^2*y - x) dx∧dy sage: s.display(eV) a∧b = (1/8*u^3 - 1/8*u*v^2 - 1/8*v^3 + 1/8*(u^2 + 2)*v + 1/4*u) du∧dv
>>> from sage.all import * >>> s = a.wedge(b) ; s 2-form a∧b on the 2-dimensional differentiable manifold M >>> s.display(eU) a∧b = (-2*x^2*y - x) dx∧dy >>> s.display(eV) a∧b = (1/8*u^3 - 1/8*u*v^2 - 1/8*v^3 + 1/8*(u^2 + 2)*v + 1/4*u) du∧dv
Multiplying a 1-form by a scalar field results in another 1-form:
sage: f = M.scalar_field({c_xy: (x+y)^2, c_uv: u^2}, name='f') sage: s = f*a ; s 1-form f*a on the 2-dimensional differentiable manifold M sage: s.display(eU) f*a = (-x^2*y - 2*x*y^2 - y^3) dx + (x^3 + 2*x^2*y + x*y^2) dy sage: s.display(eV) f*a = 1/2*u^2*v du - 1/2*u^3 dv
>>> from sage.all import * >>> f = M.scalar_field({c_xy: (x+y)**Integer(2), c_uv: u**Integer(2)}, name='f') >>> s = f*a ; s 1-form f*a on the 2-dimensional differentiable manifold M >>> s.display(eU) f*a = (-x^2*y - 2*x*y^2 - y^3) dx + (x^3 + 2*x^2*y + x*y^2) dy >>> s.display(eV) f*a = 1/2*u^2*v du - 1/2*u^3 dv
Examples with SymPy as the symbolic engine
From now on, we ask that all symbolic calculus on manifold \(M\) are performed by SymPy:
sage: M.set_calculus_method('sympy')
>>> from sage.all import * >>> M.set_calculus_method('sympy')
We define a 2-form \(a\) as above:
sage: a = M.diff_form(2, name='a') sage: a[eU,0,1] = x*y^2 + 2*x sage: a.add_comp_by_continuation(eV, W, c_uv) sage: a.display(eU) a = (x*y**2 + 2*x) dx∧dy sage: a.display(eV) a = (-u**3/16 + u**2*v/16 + u*v**2/16 - u/2 - v**3/16 - v/2) du∧dv
>>> from sage.all import * >>> a = M.diff_form(Integer(2), name='a') >>> a[eU,Integer(0),Integer(1)] = x*y**Integer(2) + Integer(2)*x >>> a.add_comp_by_continuation(eV, W, c_uv) >>> a.display(eU) a = (x*y**2 + 2*x) dx∧dy >>> a.display(eV) a = (-u**3/16 + u**2*v/16 + u*v**2/16 - u/2 - v**3/16 - v/2) du∧dv
A 1-form on
M
:sage: a = M.one_form(-y, x, name='a') sage: a.add_comp_by_continuation(eV, W, c_uv) sage: a.display(eU) a = -y dx + x dy sage: a.display(eV) a = v/2 du - u/2 dv
>>> from sage.all import * >>> a = M.one_form(-y, x, name='a') >>> a.add_comp_by_continuation(eV, W, c_uv) >>> a.display(eU) a = -y dx + x dy >>> a.display(eV) a = v/2 du - u/2 dv
The exterior derivative of
a
:sage: da = a.exterior_derivative() sage: da.display(eU) da = 2 dx∧dy sage: da.display(eV) da = -du∧dv
>>> from sage.all import * >>> da = a.exterior_derivative() >>> da.display(eU) da = 2 dx∧dy >>> da.display(eV) da = -du∧dv
Another 1-form:
sage: b = M.one_form(1+x*y, x^2, name='b') sage: b.add_comp_by_continuation(eV, W, c_uv)
>>> from sage.all import * >>> b = M.one_form(Integer(1)+x*y, x**Integer(2), name='b') >>> b.add_comp_by_continuation(eV, W, c_uv)
Adding two 1-forms:
sage: s = a + b sage: s.display(eU) a+b = (x*y - y + 1) dx + x*(x + 1) dy sage: s.display(eV) a+b = (u**2/4 + u*v/4 + v/2 + 1/2) du + (-u*v/4 - u/2 - v**2/4 + 1/2) dv
>>> from sage.all import * >>> s = a + b >>> s.display(eU) a+b = (x*y - y + 1) dx + x*(x + 1) dy >>> s.display(eV) a+b = (u**2/4 + u*v/4 + v/2 + 1/2) du + (-u*v/4 - u/2 - v**2/4 + 1/2) dv
The exterior product of two 1-forms:
sage: s = a.wedge(b) sage: s.display(eU) a∧b = x*(-2*x*y - 1) dx∧dy sage: s.display(eV) a∧b = (u**3/8 + u**2*v/8 - u*v**2/8 + u/4 - v**3/8 + v/4) du∧dv
>>> from sage.all import * >>> s = a.wedge(b) >>> s.display(eU) a∧b = x*(-2*x*y - 1) dx∧dy >>> s.display(eV) a∧b = (u**3/8 + u**2*v/8 - u*v**2/8 + u/4 - v**3/8 + v/4) du∧dv
Multiplying a 1-form by a scalar field:
sage: f = M.scalar_field({c_xy: (x+y)^2, c_uv: u^2}, name='f') sage: s = f*a sage: s.display(eU) f*a = y*(-x**2 - 2*x*y - y**2) dx + x*(x**2 + 2*x*y + y**2) dy sage: s.display(eV) f*a = u**2*v/2 du - u**3/2 dv
>>> from sage.all import * >>> f = M.scalar_field({c_xy: (x+y)**Integer(2), c_uv: u**Integer(2)}, name='f') >>> s = f*a >>> s.display(eU) f*a = y*(-x**2 - 2*x*y - y**2) dx + x*(x**2 + 2*x*y + y**2) dy >>> s.display(eV) f*a = u**2*v/2 du - u**3/2 dv
- degree()[source]¶
Return the degree of
self
.OUTPUT: integer \(p\) such that the differential form is a \(p\)-form
EXAMPLES:
sage: M = Manifold(3, 'M') sage: a = M.diff_form(2); a 2-form on the 3-dimensional differentiable manifold M sage: a.degree() 2 sage: b = M.diff_form(1); b 1-form on the 3-dimensional differentiable manifold M sage: b.degree() 1
>>> from sage.all import * >>> M = Manifold(Integer(3), 'M') >>> a = M.diff_form(Integer(2)); a 2-form on the 3-dimensional differentiable manifold M >>> a.degree() 2 >>> b = M.diff_form(Integer(1)); b 1-form on the 3-dimensional differentiable manifold M >>> b.degree() 1
- derivative()[source]¶
Compute the exterior derivative of
self
.OUTPUT:
instance of
DiffForm
representing the exterior derivative of the differential form
EXAMPLES:
Exterior derivative of a 1-form on the 2-sphere:
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2 sage: U = M.open_subset('U') # complement of the North pole sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole sage: V = M.open_subset('V') # complement of the South pole sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole sage: M.declare_union(U,V) # S^2 is the union of U and V sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)), ....: intersection_name='W', restrictions1= x^2+y^2!=0, ....: restrictions2= u^2+v^2!=0) sage: uv_to_xy = xy_to_uv.inverse() sage: e_xy = c_xy.frame(); e_uv = c_uv.frame()
>>> from sage.all import * >>> M = Manifold(Integer(2), 'M') # the 2-dimensional sphere S^2 >>> U = M.open_subset('U') # complement of the North pole >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2)# stereographic coordinates from the North pole >>> V = M.open_subset('V') # complement of the South pole >>> c_uv = V.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2)# stereographic coordinates from the South pole >>> M.declare_union(U,V) # S^2 is the union of U and V >>> xy_to_uv = c_xy.transition_map(c_uv, (x/(x**Integer(2)+y**Integer(2)), y/(x**Integer(2)+y**Integer(2))), ... intersection_name='W', restrictions1= x**Integer(2)+y**Integer(2)!=Integer(0), ... restrictions2= u**Integer(2)+v**Integer(2)!=Integer(0)) >>> uv_to_xy = xy_to_uv.inverse() >>> e_xy = c_xy.frame(); e_uv = c_uv.frame()
The 1-form:
sage: a = M.one_form({e_xy: [-y^2, x^2]}, name='a') sage: a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv) sage: a.display(e_xy) a = -y^2 dx + x^2 dy sage: a.display(e_uv) a = -(2*u^3*v - u^2*v^2 + v^4)/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) du + (u^4 - u^2*v^2 + 2*u*v^3)/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) dv
>>> from sage.all import * >>> a = M.one_form({e_xy: [-y**Integer(2), x**Integer(2)]}, name='a') >>> a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv) >>> a.display(e_xy) a = -y^2 dx + x^2 dy >>> a.display(e_uv) a = -(2*u^3*v - u^2*v^2 + v^4)/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) du + (u^4 - u^2*v^2 + 2*u*v^3)/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) dv
Its exterior derivative:
sage: da = a.exterior_derivative(); da 2-form da on the 2-dimensional differentiable manifold M sage: da.display(e_xy) da = (2*x + 2*y) dx∧dy sage: da.display(e_uv) da = -2*(u + v)/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) du∧dv
>>> from sage.all import * >>> da = a.exterior_derivative(); da 2-form da on the 2-dimensional differentiable manifold M >>> da.display(e_xy) da = (2*x + 2*y) dx∧dy >>> da.display(e_uv) da = -2*(u + v)/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) du∧dv
The result is cached, i.e. is not recomputed unless
a
is changed:sage: a.exterior_derivative() is da True
>>> from sage.all import * >>> a.exterior_derivative() is da True
Instead of invoking the method
exterior_derivative()
, one may use the global functiondiff
:sage: diff(a) is a.exterior_derivative() True
>>> from sage.all import * >>> diff(a) is a.exterior_derivative() True
Let us check Cartan’s identity:
sage: v = M.vector_field({e_xy: [-y, x]}, name='v') sage: v.add_comp_by_continuation(e_uv, U.intersection(V), c_uv) sage: a.lie_der(v) == v.contract(diff(a)) + diff(a(v)) # long time True
>>> from sage.all import * >>> v = M.vector_field({e_xy: [-y, x]}, name='v') >>> v.add_comp_by_continuation(e_uv, U.intersection(V), c_uv) >>> a.lie_der(v) == v.contract(diff(a)) + diff(a(v)) # long time True
- exterior_derivative()[source]¶
Compute the exterior derivative of
self
.OUTPUT:
instance of
DiffForm
representing the exterior derivative of the differential form
EXAMPLES:
Exterior derivative of a 1-form on the 2-sphere:
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2 sage: U = M.open_subset('U') # complement of the North pole sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole sage: V = M.open_subset('V') # complement of the South pole sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole sage: M.declare_union(U,V) # S^2 is the union of U and V sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)), ....: intersection_name='W', restrictions1= x^2+y^2!=0, ....: restrictions2= u^2+v^2!=0) sage: uv_to_xy = xy_to_uv.inverse() sage: e_xy = c_xy.frame(); e_uv = c_uv.frame()
>>> from sage.all import * >>> M = Manifold(Integer(2), 'M') # the 2-dimensional sphere S^2 >>> U = M.open_subset('U') # complement of the North pole >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2)# stereographic coordinates from the North pole >>> V = M.open_subset('V') # complement of the South pole >>> c_uv = V.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2)# stereographic coordinates from the South pole >>> M.declare_union(U,V) # S^2 is the union of U and V >>> xy_to_uv = c_xy.transition_map(c_uv, (x/(x**Integer(2)+y**Integer(2)), y/(x**Integer(2)+y**Integer(2))), ... intersection_name='W', restrictions1= x**Integer(2)+y**Integer(2)!=Integer(0), ... restrictions2= u**Integer(2)+v**Integer(2)!=Integer(0)) >>> uv_to_xy = xy_to_uv.inverse() >>> e_xy = c_xy.frame(); e_uv = c_uv.frame()
The 1-form:
sage: a = M.one_form({e_xy: [-y^2, x^2]}, name='a') sage: a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv) sage: a.display(e_xy) a = -y^2 dx + x^2 dy sage: a.display(e_uv) a = -(2*u^3*v - u^2*v^2 + v^4)/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) du + (u^4 - u^2*v^2 + 2*u*v^3)/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) dv
>>> from sage.all import * >>> a = M.one_form({e_xy: [-y**Integer(2), x**Integer(2)]}, name='a') >>> a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv) >>> a.display(e_xy) a = -y^2 dx + x^2 dy >>> a.display(e_uv) a = -(2*u^3*v - u^2*v^2 + v^4)/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) du + (u^4 - u^2*v^2 + 2*u*v^3)/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) dv
Its exterior derivative:
sage: da = a.exterior_derivative(); da 2-form da on the 2-dimensional differentiable manifold M sage: da.display(e_xy) da = (2*x + 2*y) dx∧dy sage: da.display(e_uv) da = -2*(u + v)/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) du∧dv
>>> from sage.all import * >>> da = a.exterior_derivative(); da 2-form da on the 2-dimensional differentiable manifold M >>> da.display(e_xy) da = (2*x + 2*y) dx∧dy >>> da.display(e_uv) da = -2*(u + v)/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) du∧dv
The result is cached, i.e. is not recomputed unless
a
is changed:sage: a.exterior_derivative() is da True
>>> from sage.all import * >>> a.exterior_derivative() is da True
Instead of invoking the method
exterior_derivative()
, one may use the global functiondiff
:sage: diff(a) is a.exterior_derivative() True
>>> from sage.all import * >>> diff(a) is a.exterior_derivative() True
Let us check Cartan’s identity:
sage: v = M.vector_field({e_xy: [-y, x]}, name='v') sage: v.add_comp_by_continuation(e_uv, U.intersection(V), c_uv) sage: a.lie_der(v) == v.contract(diff(a)) + diff(a(v)) # long time True
>>> from sage.all import * >>> v = M.vector_field({e_xy: [-y, x]}, name='v') >>> v.add_comp_by_continuation(e_uv, U.intersection(V), c_uv) >>> a.lie_der(v) == v.contract(diff(a)) + diff(a(v)) # long time True
- hodge_dual(nondegenerate_tensor=None, minus_eigenvalues_convention=False)[source]¶
Compute the Hodge dual of the differential form with respect to some non-degenerate bilinear form (Riemannian metric or symplectic form).
If the differential form is a \(p\)-form \(A\), its Hodge dual with respect to the non-degenerate form \(g\) is the \((n-p)\)-form \(*A\) defined by
\[*A_{i_1\ldots i_{n-p}} = \frac{1}{p!} A^{k_1\ldots k_p} \epsilon_{k_1\ldots k_p\, i_1\ldots i_{n-p}}\]where \(n\) is the manifold’s dimension, \(\epsilon\) is the volume \(n\)-form associated with \(g\) (see
volume_form()
) and the indices \(k_1,\ldots, k_p\) are raised with \(g\). If \(g\) is a pseudo-Riemannian metric, sometimes an additional multiplicative factor of \((-1)^s\) is introduced on the right-hand side, where \(s\) is the number of negative eigenvalues of \(g\). This convention can be enforced by setting the optionminus_eigenvalues_convention
.INPUT:
nondegenerate_tensor
– a non-degenerate bilinear form defined on the same manifold as the current differential form; must be an instance ofPseudoRiemannianMetric
orSymplecticForm
. If none is provided, the ambient domain ofself
is supposed to be endowed with a default metric and this metric is then used.minus_eigenvalues_convention
– if \(true\), a factor of \((-1)^s\) isintroduced with \(s\) being the number of negative eigenvalues of the
nondegenerate_tensor
.
OUTPUT:
the \((n-p)\)-form \(*A\)
EXAMPLES:
Hodge dual of a 1-form on the 2-sphere equipped with the standard metric: we first construct \(\mathbb{S}^2\) and its metric \(g\):
sage: M = Manifold(2, 'S^2', start_index=1) sage: U = M.open_subset('U') ; V = M.open_subset('V') sage: M.declare_union(U,V) # S^2 is the union of U and V sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart() # stereographic coord. (North and South) sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)), ....: intersection_name='W', restrictions1= x^2+y^2!=0, ....: restrictions2= u^2+v^2!=0) sage: uv_to_xy = xy_to_uv.inverse() sage: W = U.intersection(V) # The complement of the two poles sage: eU = c_xy.frame() ; eV = c_uv.frame() sage: g = M.metric('g') sage: g[eU,1,1], g[eU,2,2] = 4/(1+x^2+y^2)^2, 4/(1+x^2+y^2)^2 sage: g[eV,1,1], g[eV,2,2] = 4/(1+u^2+v^2)^2, 4/(1+u^2+v^2)^2
>>> from sage.all import * >>> M = Manifold(Integer(2), 'S^2', start_index=Integer(1)) >>> U = M.open_subset('U') ; V = M.open_subset('V') >>> M.declare_union(U,V) # S^2 is the union of U and V >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2); c_uv = V.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2)# stereographic coord. (North and South) >>> xy_to_uv = c_xy.transition_map(c_uv, (x/(x**Integer(2)+y**Integer(2)), y/(x**Integer(2)+y**Integer(2))), ... intersection_name='W', restrictions1= x**Integer(2)+y**Integer(2)!=Integer(0), ... restrictions2= u**Integer(2)+v**Integer(2)!=Integer(0)) >>> uv_to_xy = xy_to_uv.inverse() >>> W = U.intersection(V) # The complement of the two poles >>> eU = c_xy.frame() ; eV = c_uv.frame() >>> g = M.metric('g') >>> g[eU,Integer(1),Integer(1)], g[eU,Integer(2),Integer(2)] = Integer(4)/(Integer(1)+x**Integer(2)+y**Integer(2))**Integer(2), Integer(4)/(Integer(1)+x**Integer(2)+y**Integer(2))**Integer(2) >>> g[eV,Integer(1),Integer(1)], g[eV,Integer(2),Integer(2)] = Integer(4)/(Integer(1)+u**Integer(2)+v**Integer(2))**Integer(2), Integer(4)/(Integer(1)+u**Integer(2)+v**Integer(2))**Integer(2)
We endow \(S^2\) with the orientation defined by the stereographic frame from the North pole, i.e.
eU
;eV
is then left-handed and in order to define an orientation on the whole manifold, we introduce a vector frame onV
by swappingeV
’s vectors:sage: f = V.vector_frame('f', (eV[2], eV[1])) sage: M.set_orientation([eU, f])
>>> from sage.all import * >>> f = V.vector_frame('f', (eV[Integer(2)], eV[Integer(1)])) >>> M.set_orientation([eU, f])
Then we construct the 1-form and take its Hodge dual w.r.t. \(g\):
sage: a = M.one_form({eU: [-y, x]}, name='a') sage: a.add_comp_by_continuation(eV, W, c_uv) sage: a.display(eU) a = -y dx + x dy sage: a.display(eV) a = -v/(u^4 + 2*u^2*v^2 + v^4) du + u/(u^4 + 2*u^2*v^2 + v^4) dv sage: sa = a.hodge_dual(g); sa 1-form *a on the 2-dimensional differentiable manifold S^2 sage: sa.display(eU) *a = -x dx - y dy sage: sa.display(eV) *a = u/(u^4 + 2*u^2*v^2 + v^4) du + v/(u^4 + 2*u^2*v^2 + v^4) dv
>>> from sage.all import * >>> a = M.one_form({eU: [-y, x]}, name='a') >>> a.add_comp_by_continuation(eV, W, c_uv) >>> a.display(eU) a = -y dx + x dy >>> a.display(eV) a = -v/(u^4 + 2*u^2*v^2 + v^4) du + u/(u^4 + 2*u^2*v^2 + v^4) dv >>> sa = a.hodge_dual(g); sa 1-form *a on the 2-dimensional differentiable manifold S^2 >>> sa.display(eU) *a = -x dx - y dy >>> sa.display(eV) *a = u/(u^4 + 2*u^2*v^2 + v^4) du + v/(u^4 + 2*u^2*v^2 + v^4) dv
Instead of calling the method
hodge_dual()
on the differential form, one can invoke the methodhodge_star()
of the metric:sage: a.hodge_dual(g) == g.hodge_star(a) True
>>> from sage.all import * >>> a.hodge_dual(g) == g.hodge_star(a) True
For a 1-form and a Riemannian metric in dimension 2, the Hodge dual applied twice is minus the identity:
sage: ssa = sa.hodge_dual(g); ssa 1-form **a on the 2-dimensional differentiable manifold S^2 sage: ssa == -a True
>>> from sage.all import * >>> ssa = sa.hodge_dual(g); ssa 1-form **a on the 2-dimensional differentiable manifold S^2 >>> ssa == -a True
The Hodge dual of the metric volume 2-form is the constant scalar field 1 (considered as a 0-form):
sage: eps = g.volume_form(); eps 2-form eps_g on the 2-dimensional differentiable manifold S^2 sage: eps.display(eU) eps_g = 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) dx∧dy sage: eps.display(eV) eps_g = -4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) du∧dv sage: seps = eps.hodge_dual(g); seps Scalar field *eps_g on the 2-dimensional differentiable manifold S^2 sage: seps.display() *eps_g: S^2 → ℝ on U: (x, y) ↦ 1 on V: (u, v) ↦ 1
>>> from sage.all import * >>> eps = g.volume_form(); eps 2-form eps_g on the 2-dimensional differentiable manifold S^2 >>> eps.display(eU) eps_g = 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) dx∧dy >>> eps.display(eV) eps_g = -4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) du∧dv >>> seps = eps.hodge_dual(g); seps Scalar field *eps_g on the 2-dimensional differentiable manifold S^2 >>> seps.display() *eps_g: S^2 → ℝ on U: (x, y) ↦ 1 on V: (u, v) ↦ 1
Hodge dual of a 1-form in the Euclidean space \(R^3\):
sage: M = Manifold(3, 'M', start_index=1) sage: X.<x,y,z> = M.chart() sage: g = M.metric('g') # the Euclidean metric sage: g[1,1], g[2,2], g[3,3] = 1, 1, 1 sage: var('Ax Ay Az') (Ax, Ay, Az) sage: a = M.one_form(Ax, Ay, Az, name='A') sage: sa = a.hodge_dual(g) ; sa 2-form *A on the 3-dimensional differentiable manifold M sage: sa.display() *A = Az dx∧dy - Ay dx∧dz + Ax dy∧dz sage: ssa = sa.hodge_dual(g) ; ssa 1-form **A on the 3-dimensional differentiable manifold M sage: ssa.display() **A = Ax dx + Ay dy + Az dz sage: ssa == a # must hold for a Riemannian metric in dimension 3 True
>>> from sage.all import * >>> M = Manifold(Integer(3), 'M', start_index=Integer(1)) >>> X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3) >>> g = M.metric('g') # the Euclidean metric >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = Integer(1), Integer(1), Integer(1) >>> var('Ax Ay Az') (Ax, Ay, Az) >>> a = M.one_form(Ax, Ay, Az, name='A') >>> sa = a.hodge_dual(g) ; sa 2-form *A on the 3-dimensional differentiable manifold M >>> sa.display() *A = Az dx∧dy - Ay dx∧dz + Ax dy∧dz >>> ssa = sa.hodge_dual(g) ; ssa 1-form **A on the 3-dimensional differentiable manifold M >>> ssa.display() **A = Ax dx + Ay dy + Az dz >>> ssa == a # must hold for a Riemannian metric in dimension 3 True
See the documentation of
hodge_star()
for more examples.
- interior_product(qvect)[source]¶
Interior product with a multivector field.
If
self
is a differential form \(A\) of degree \(p\) and \(B\) is a multivector field of degree \(q\geq p\) on the same manifold, the interior product of \(A\) by \(B\) is the multivector field \(\iota_A B\) of degree \(q-p\) defined by\[(\iota_A B)^{i_1\ldots i_{q-p}} = A_{k_1\ldots k_p} B^{k_1\ldots k_p i_1\ldots i_{q-p}}\]Note
A.interior_product(B)
yields the same result asA.contract(0,..., p-1, B, 0,..., p-1)
(cf.contract()
), butinterior_product
is more efficient, the alternating character of \(A\) being not used to reduce the computation incontract()
INPUT:
qvect
– multivector field \(B\) (instance ofMultivectorField
); the degree of \(B\) must be at least equal to the degree ofself
OUTPUT:
scalar field (case \(p=q\)) or
MultivectorField
(case \(p<q\)) representing the interior product \(\iota_A B\), where \(A\) isself
See also
interior_product()
for the interior product of a multivector field with a differential formEXAMPLES:
Interior product of a 1-form with a 2-vector field on the 2-sphere:
sage: M = Manifold(2, 'S^2', start_index=1) # the sphere S^2 sage: U = M.open_subset('U') ; V = M.open_subset('V') sage: M.declare_union(U,V) # S^2 is the union of U and V sage: c_xy.<x,y> = U.chart() # stereographic coord. North sage: c_uv.<u,v> = V.chart() # stereographic coord. South sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)), ....: intersection_name='W', restrictions1= x^2+y^2!=0, ....: restrictions2= u^2+v^2!=0) sage: uv_to_xy = xy_to_uv.inverse() sage: W = U.intersection(V) # The complement of the two poles sage: e_xy = c_xy.frame() ; e_uv = c_uv.frame() sage: a = M.one_form({e_xy: [y, x]}, name='a') sage: a.add_comp_by_continuation(e_uv, W, c_uv) sage: b = M.multivector_field(2, name='b') sage: b[e_xy,1,2] = x*y sage: b.add_comp_by_continuation(e_uv, W, c_uv) sage: s = a.interior_product(b); s Vector field i_a b on the 2-dimensional differentiable manifold S^2 sage: s.display(e_xy) i_a b = -x^2*y ∂/∂x + x*y^2 ∂/∂y sage: s.display(e_uv) i_a b = (u^4*v - 3*u^2*v^3)/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) ∂/∂u + (3*u^3*v^2 - u*v^4)/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) ∂/∂v sage: s == a.contract(b) True
>>> from sage.all import * >>> M = Manifold(Integer(2), 'S^2', start_index=Integer(1)) # the sphere S^2 >>> U = M.open_subset('U') ; V = M.open_subset('V') >>> M.declare_union(U,V) # S^2 is the union of U and V >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2)# stereographic coord. North >>> c_uv = V.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2)# stereographic coord. South >>> xy_to_uv = c_xy.transition_map(c_uv, (x/(x**Integer(2)+y**Integer(2)), y/(x**Integer(2)+y**Integer(2))), ... intersection_name='W', restrictions1= x**Integer(2)+y**Integer(2)!=Integer(0), ... restrictions2= u**Integer(2)+v**Integer(2)!=Integer(0)) >>> uv_to_xy = xy_to_uv.inverse() >>> W = U.intersection(V) # The complement of the two poles >>> e_xy = c_xy.frame() ; e_uv = c_uv.frame() >>> a = M.one_form({e_xy: [y, x]}, name='a') >>> a.add_comp_by_continuation(e_uv, W, c_uv) >>> b = M.multivector_field(Integer(2), name='b') >>> b[e_xy,Integer(1),Integer(2)] = x*y >>> b.add_comp_by_continuation(e_uv, W, c_uv) >>> s = a.interior_product(b); s Vector field i_a b on the 2-dimensional differentiable manifold S^2 >>> s.display(e_xy) i_a b = -x^2*y ∂/∂x + x*y^2 ∂/∂y >>> s.display(e_uv) i_a b = (u^4*v - 3*u^2*v^3)/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) ∂/∂u + (3*u^3*v^2 - u*v^4)/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) ∂/∂v >>> s == a.contract(b) True
Interior product of a 2-form with a 2-vector field:
sage: a = M.diff_form(2, name='a') sage: a[e_xy,1,2] = 4/(x^2+y^2+1)^2 # the standard area 2-form sage: a.add_comp_by_continuation(e_uv, W, c_uv) sage: s = a.interior_product(b); s Scalar field i_a b on the 2-dimensional differentiable manifold S^2 sage: s.display() i_a b: S^2 → ℝ on U: (x, y) ↦ 8*x*y/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) on V: (u, v) ↦ 8*u*v/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1)
>>> from sage.all import * >>> a = M.diff_form(Integer(2), name='a') >>> a[e_xy,Integer(1),Integer(2)] = Integer(4)/(x**Integer(2)+y**Integer(2)+Integer(1))**Integer(2) # the standard area 2-form >>> a.add_comp_by_continuation(e_uv, W, c_uv) >>> s = a.interior_product(b); s Scalar field i_a b on the 2-dimensional differentiable manifold S^2 >>> s.display() i_a b: S^2 → ℝ on U: (x, y) ↦ 8*x*y/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) on V: (u, v) ↦ 8*u*v/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1)
Some checks:
sage: s == a.contract(0, 1, b, 0, 1) True sage: s.restrict(U) == 2 * a[[e_xy,1,2]] * b[[e_xy,1,2]] True sage: s.restrict(V) == 2 * a[[e_uv,1,2]] * b[[e_uv,1,2]] True
>>> from sage.all import * >>> s == a.contract(Integer(0), Integer(1), b, Integer(0), Integer(1)) True >>> s.restrict(U) == Integer(2) * a[[e_xy,Integer(1),Integer(2)]] * b[[e_xy,Integer(1),Integer(2)]] True >>> s.restrict(V) == Integer(2) * a[[e_uv,Integer(1),Integer(2)]] * b[[e_uv,Integer(1),Integer(2)]] True
- wedge(other)[source]¶
Exterior product with another differential form.
INPUT:
other
– another differential form (on the same manifold)
OUTPUT:
instance of
DiffForm
representing the exterior productself ∧ other
EXAMPLES:
Exterior product of two 1-forms on the 2-sphere:
sage: M = Manifold(2, 'S^2', start_index=1) # the 2-dimensional sphere S^2 sage: U = M.open_subset('U') ; V = M.open_subset('V') sage: M.declare_union(U,V) # S^2 is the union of U and V sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart() # stereographic coord. (North and South) sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)), ....: intersection_name='W', restrictions1= x^2+y^2!=0, ....: restrictions2= u^2+v^2!=0) sage: uv_to_xy = xy_to_uv.inverse() sage: W = U.intersection(V) # The complement of the two poles sage: e_xy = c_xy.frame() ; e_uv = c_uv.frame() sage: a = M.one_form({e_xy: [y, x]}, name='a') sage: a.add_comp_by_continuation(e_uv, W, c_uv) sage: b = M.one_form({e_xy: [x^2 + y^2, y]}, name='b') sage: b.add_comp_by_continuation(e_uv, W, c_uv) sage: c = a.wedge(b); c 2-form a∧b on the 2-dimensional differentiable manifold S^2 sage: c.display(e_xy) a∧b = (-x^3 - (x - 1)*y^2) dx∧dy sage: c.display(e_uv) a∧b = -(v^2 - u)/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) du∧dv
>>> from sage.all import * >>> M = Manifold(Integer(2), 'S^2', start_index=Integer(1)) # the 2-dimensional sphere S^2 >>> U = M.open_subset('U') ; V = M.open_subset('V') >>> M.declare_union(U,V) # S^2 is the union of U and V >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2); c_uv = V.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2)# stereographic coord. (North and South) >>> xy_to_uv = c_xy.transition_map(c_uv, (x/(x**Integer(2)+y**Integer(2)), y/(x**Integer(2)+y**Integer(2))), ... intersection_name='W', restrictions1= x**Integer(2)+y**Integer(2)!=Integer(0), ... restrictions2= u**Integer(2)+v**Integer(2)!=Integer(0)) >>> uv_to_xy = xy_to_uv.inverse() >>> W = U.intersection(V) # The complement of the two poles >>> e_xy = c_xy.frame() ; e_uv = c_uv.frame() >>> a = M.one_form({e_xy: [y, x]}, name='a') >>> a.add_comp_by_continuation(e_uv, W, c_uv) >>> b = M.one_form({e_xy: [x**Integer(2) + y**Integer(2), y]}, name='b') >>> b.add_comp_by_continuation(e_uv, W, c_uv) >>> c = a.wedge(b); c 2-form a∧b on the 2-dimensional differentiable manifold S^2 >>> c.display(e_xy) a∧b = (-x^3 - (x - 1)*y^2) dx∧dy >>> c.display(e_uv) a∧b = -(v^2 - u)/(u^8 + 4*u^6*v^2 + 6*u^4*v^4 + 4*u^2*v^6 + v^8) du∧dv
If one of the two operands is unnamed, the result is unnamed too:
sage: b1 = M.diff_form(1) # no name set sage: b1[e_xy,:] = x^2 + y^2, y sage: b1.add_comp_by_continuation(e_uv, W, c_uv) sage: c1 = a.wedge(b1); c1 2-form on the 2-dimensional differentiable manifold S^2 sage: c1.display(e_xy) (-x^3 - (x - 1)*y^2) dx∧dy
>>> from sage.all import * >>> b1 = M.diff_form(Integer(1)) # no name set >>> b1[e_xy,:] = x**Integer(2) + y**Integer(2), y >>> b1.add_comp_by_continuation(e_uv, W, c_uv) >>> c1 = a.wedge(b1); c1 2-form on the 2-dimensional differentiable manifold S^2 >>> c1.display(e_xy) (-x^3 - (x - 1)*y^2) dx∧dy
To give a name to the result, one shall use the method
set_name()
:sage: c1.set_name('c'); c1 2-form c on the 2-dimensional differentiable manifold S^2 sage: c1.display(e_xy) c = (-x^3 - (x - 1)*y^2) dx∧dy
>>> from sage.all import * >>> c1.set_name('c'); c1 2-form c on the 2-dimensional differentiable manifold S^2 >>> c1.display(e_xy) c = (-x^3 - (x - 1)*y^2) dx∧dy
Wedging with scalar fields yields the multiplication from right:
sage: f = M.scalar_field(x, name='f') sage: f.add_expr_by_continuation(c_uv, W) sage: t = a.wedge(f) sage: t.display() f*a = x*y dx + x^2 dy
>>> from sage.all import * >>> f = M.scalar_field(x, name='f') >>> f.add_expr_by_continuation(c_uv, W) >>> t = a.wedge(f) >>> t.display() f*a = x*y dx + x^2 dy
- class sage.manifolds.differentiable.diff_form.DiffFormParal(vector_field_module: VectorFieldModule, degree: int, name: str | None = None, latex_name: str | None = None)[source]¶
Bases:
FreeModuleAltForm
,TensorFieldParal
,DiffForm
Differential form with values on a parallelizable manifold.
Given a differentiable manifold \(U\), a differentiable map \(\Phi: U \rightarrow M\) to a parallelizable manifold \(M\) and a positive integer \(p\), a differential form of degree \(p\) (or \(p\)-form) along \(U\) with values on \(M\supset\Phi(U)\) is a differentiable map
\[a:\ U \longrightarrow T^{(0,p)}M\](\(T^{(0,p)}M\) being the tensor bundle of type \((0,p)\) over \(M\)) such that
\[\forall x \in U,\quad a(x) \in \Lambda^p(T_{\Phi(x)}^* M) ,\]where \(T_{\Phi(x)}^* M\) is the dual of the tangent space to \(M\) at \(\Phi(x)\) and \(\Lambda^p\) stands for the exterior power of degree \(p\) (cf.
ExtPowerDualFreeModule
). In other words, \(a(x)\) is an alternating multilinear form of degree \(p\) of the tangent vector space \(T_{\Phi(x)} M\).The standard case of a differential form on a manifold \(M\) corresponds to \(U = M\) and \(\Phi = \mathrm{Id}_M\). Other common cases are \(\Phi\) being an immersion and \(\Phi\) being a curve in \(M\) (\(U\) is then an open interval of \(\RR\)).
Note
If \(M\) is not parallelizable, the class
DiffForm
must be used instead.INPUT:
vector_field_module
– free module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(M\) via the map \(\Phi\)degree
– the degree of the differential form (i.e. its tensor rank)name
– (default:None
) name given to the differential formlatex_name
– (default:None
) LaTeX symbol to denote the differential form; if none is provided, the LaTeX symbol is set toname
EXAMPLES:
A 2-form on a 4-dimensional manifold:
sage: M = Manifold(4, 'M') sage: c_txyz.<t,x,y,z> = M.chart() sage: a = M.diff_form(2, name='a') ; a 2-form a on the 4-dimensional differentiable manifold M sage: a.parent() Free module Omega^2(M) of 2-forms on the 4-dimensional differentiable manifold M
>>> from sage.all import * >>> M = Manifold(Integer(4), 'M') >>> c_txyz = M.chart(names=('t', 'x', 'y', 'z',)); (t, x, y, z,) = c_txyz._first_ngens(4) >>> a = M.diff_form(Integer(2), name='a') ; a 2-form a on the 4-dimensional differentiable manifold M >>> a.parent() Free module Omega^2(M) of 2-forms on the 4-dimensional differentiable manifold M
A differential form is a tensor field of purely covariant type:
sage: a.tensor_type() (0, 2)
>>> from sage.all import * >>> a.tensor_type() (0, 2)
It is antisymmetric, its components being
CompFullyAntiSym
:sage: a.symmetries() no symmetry; antisymmetry: (0, 1) sage: a[0,1] = 2 sage: a[1,0] -2 sage: a.comp() Fully antisymmetric 2-indices components w.r.t. Coordinate frame (M, (∂/∂t,∂/∂x,∂/∂y,∂/∂z)) sage: type(a.comp()) <class 'sage.tensor.modules.comp.CompFullyAntiSym'>
>>> from sage.all import * >>> a.symmetries() no symmetry; antisymmetry: (0, 1) >>> a[Integer(0),Integer(1)] = Integer(2) >>> a[Integer(1),Integer(0)] -2 >>> a.comp() Fully antisymmetric 2-indices components w.r.t. Coordinate frame (M, (∂/∂t,∂/∂x,∂/∂y,∂/∂z)) >>> type(a.comp()) <class 'sage.tensor.modules.comp.CompFullyAntiSym'>
Setting a component with repeated indices to a nonzero value results in an error:
sage: a[1,1] = 3 Traceback (most recent call last): ... ValueError: by antisymmetry, the component cannot have a nonzero value for the indices (1, 1) sage: a[1,1] = 0 # OK, albeit useless sage: a[1,2] = 3 # OK
>>> from sage.all import * >>> a[Integer(1),Integer(1)] = Integer(3) Traceback (most recent call last): ... ValueError: by antisymmetry, the component cannot have a nonzero value for the indices (1, 1) >>> a[Integer(1),Integer(1)] = Integer(0) # OK, albeit useless >>> a[Integer(1),Integer(2)] = Integer(3) # OK
The expansion of a differential form with respect to a given coframe is displayed via the method
display()
:sage: a.display() # expansion with respect to the default coframe (dt, dx, dy, dz) a = 2 dt∧dx + 3 dx∧dy sage: latex(a.display()) # output for the notebook a = 2 \mathrm{d} t\wedge \mathrm{d} x + 3 \mathrm{d} x\wedge \mathrm{d} y
>>> from sage.all import * >>> a.display() # expansion with respect to the default coframe (dt, dx, dy, dz) a = 2 dt∧dx + 3 dx∧dy >>> latex(a.display()) # output for the notebook a = 2 \mathrm{d} t\wedge \mathrm{d} x + 3 \mathrm{d} x\wedge \mathrm{d} y
Differential forms can be added or subtracted:
sage: b = M.diff_form(2) sage: b[0,1], b[0,2], b[0,3] = (1,2,3) sage: s = a + b ; s 2-form on the 4-dimensional differentiable manifold M sage: a[:], b[:], s[:] ( [ 0 2 0 0] [ 0 1 2 3] [ 0 3 2 3] [-2 0 3 0] [-1 0 0 0] [-3 0 3 0] [ 0 -3 0 0] [-2 0 0 0] [-2 -3 0 0] [ 0 0 0 0], [-3 0 0 0], [-3 0 0 0] ) sage: s = a - b ; s 2-form on the 4-dimensional differentiable manifold M sage: s[:] [ 0 1 -2 -3] [-1 0 3 0] [ 2 -3 0 0] [ 3 0 0 0]
>>> from sage.all import * >>> b = M.diff_form(Integer(2)) >>> b[Integer(0),Integer(1)], b[Integer(0),Integer(2)], b[Integer(0),Integer(3)] = (Integer(1),Integer(2),Integer(3)) >>> s = a + b ; s 2-form on the 4-dimensional differentiable manifold M >>> a[:], b[:], s[:] ( [ 0 2 0 0] [ 0 1 2 3] [ 0 3 2 3] [-2 0 3 0] [-1 0 0 0] [-3 0 3 0] [ 0 -3 0 0] [-2 0 0 0] [-2 -3 0 0] [ 0 0 0 0], [-3 0 0 0], [-3 0 0 0] ) >>> s = a - b ; s 2-form on the 4-dimensional differentiable manifold M >>> s[:] [ 0 1 -2 -3] [-1 0 3 0] [ 2 -3 0 0] [ 3 0 0 0]
An example of 3-form is the volume element on \(\RR^3\) in Cartesian coordinates:
sage: M = Manifold(3, 'R3', latex_name=r'\RR^3', start_index=1) sage: c_cart.<x,y,z> = M.chart() sage: eps = M.diff_form(3, name='epsilon', latex_name=r'\epsilon') sage: eps[1,2,3] = 1 # the only independent component sage: eps[:] # all the components are set from the previous line: [[[0, 0, 0], [0, 0, 1], [0, -1, 0]], [[0, 0, -1], [0, 0, 0], [1, 0, 0]], [[0, 1, 0], [-1, 0, 0], [0, 0, 0]]] sage: eps.display() epsilon = dx∧dy∧dz
>>> from sage.all import * >>> M = Manifold(Integer(3), 'R3', latex_name=r'\RR^3', start_index=Integer(1)) >>> c_cart = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = c_cart._first_ngens(3) >>> eps = M.diff_form(Integer(3), name='epsilon', latex_name=r'\epsilon') >>> eps[Integer(1),Integer(2),Integer(3)] = Integer(1) # the only independent component >>> eps[:] # all the components are set from the previous line: [[[0, 0, 0], [0, 0, 1], [0, -1, 0]], [[0, 0, -1], [0, 0, 0], [1, 0, 0]], [[0, 1, 0], [-1, 0, 0], [0, 0, 0]]] >>> eps.display() epsilon = dx∧dy∧dz
Spherical components of the volume element from the tensorial change-of-frame formula:
sage: c_spher.<r,th,ph> = M.chart(r'r:[0,+oo) th:[0,pi]:\theta ph:[0,2*pi):\phi') sage: spher_to_cart = c_spher.transition_map(c_cart, ....: [r*sin(th)*cos(ph), r*sin(th)*sin(ph), r*cos(th)]) sage: cart_to_spher = spher_to_cart.set_inverse(sqrt(x^2+y^2+z^2), ....: atan2(sqrt(x^2+y^2),z), atan2(y, x)) Check of the inverse coordinate transformation: r == r *passed* th == arctan2(r*sin(th), r*cos(th)) **failed** ph == arctan2(r*sin(ph)*sin(th), r*cos(ph)*sin(th)) **failed** x == x *passed* y == y *passed* z == z *passed* NB: a failed report can reflect a mere lack of simplification. sage: eps.comp(c_spher.frame()) # computation of the components in the spherical frame Fully antisymmetric 3-indices components w.r.t. Coordinate frame (R3, (∂/∂r,∂/∂th,∂/∂ph)) sage: eps.comp(c_spher.frame())[1,2,3, c_spher] r^2*sin(th) sage: eps.display(c_spher.frame()) epsilon = sqrt(x^2 + y^2 + z^2)*sqrt(x^2 + y^2) dr∧dth∧dph sage: eps.display(c_spher.frame(), c_spher) epsilon = r^2*sin(th) dr∧dth∧dph
>>> from sage.all import * >>> c_spher = M.chart(r'r:[0,+oo) th:[0,pi]:\theta ph:[0,2*pi):\phi', names=('r', 'th', 'ph',)); (r, th, ph,) = c_spher._first_ngens(3) >>> spher_to_cart = c_spher.transition_map(c_cart, ... [r*sin(th)*cos(ph), r*sin(th)*sin(ph), r*cos(th)]) >>> cart_to_spher = spher_to_cart.set_inverse(sqrt(x**Integer(2)+y**Integer(2)+z**Integer(2)), ... atan2(sqrt(x**Integer(2)+y**Integer(2)),z), atan2(y, x)) Check of the inverse coordinate transformation: r == r *passed* th == arctan2(r*sin(th), r*cos(th)) **failed** ph == arctan2(r*sin(ph)*sin(th), r*cos(ph)*sin(th)) **failed** x == x *passed* y == y *passed* z == z *passed* NB: a failed report can reflect a mere lack of simplification. >>> eps.comp(c_spher.frame()) # computation of the components in the spherical frame Fully antisymmetric 3-indices components w.r.t. Coordinate frame (R3, (∂/∂r,∂/∂th,∂/∂ph)) >>> eps.comp(c_spher.frame())[Integer(1),Integer(2),Integer(3), c_spher] r^2*sin(th) >>> eps.display(c_spher.frame()) epsilon = sqrt(x^2 + y^2 + z^2)*sqrt(x^2 + y^2) dr∧dth∧dph >>> eps.display(c_spher.frame(), c_spher) epsilon = r^2*sin(th) dr∧dth∧dph
As a shortcut of the above command, on can pass just the chart
c_spher
todisplay
, the vector frame being then assumed to be the coordinate frame associated with the chart:sage: eps.display(c_spher) epsilon = r^2*sin(th) dr∧dth∧dph
>>> from sage.all import * >>> eps.display(c_spher) epsilon = r^2*sin(th) dr∧dth∧dph
The exterior product of two differential forms is performed via the method
wedge()
:sage: a = M.one_form(x*y*z, -z*x, y*z, name='A') sage: b = M.one_form(cos(z), sin(x), cos(y), name='B') sage: ab = a.wedge(b) ; ab 2-form A∧B on the 3-dimensional differentiable manifold R3 sage: ab[:] [ 0 x*y*z*sin(x) + x*z*cos(z) x*y*z*cos(y) - y*z*cos(z)] [-x*y*z*sin(x) - x*z*cos(z) 0 -(x*cos(y) + y*sin(x))*z] [-x*y*z*cos(y) + y*z*cos(z) (x*cos(y) + y*sin(x))*z 0] sage: ab.display() A∧B = (x*y*z*sin(x) + x*z*cos(z)) dx∧dy + (x*y*z*cos(y) - y*z*cos(z)) dx∧dz - (x*cos(y) + y*sin(x))*z dy∧dz
>>> from sage.all import * >>> a = M.one_form(x*y*z, -z*x, y*z, name='A') >>> b = M.one_form(cos(z), sin(x), cos(y), name='B') >>> ab = a.wedge(b) ; ab 2-form A∧B on the 3-dimensional differentiable manifold R3 >>> ab[:] [ 0 x*y*z*sin(x) + x*z*cos(z) x*y*z*cos(y) - y*z*cos(z)] [-x*y*z*sin(x) - x*z*cos(z) 0 -(x*cos(y) + y*sin(x))*z] [-x*y*z*cos(y) + y*z*cos(z) (x*cos(y) + y*sin(x))*z 0] >>> ab.display() A∧B = (x*y*z*sin(x) + x*z*cos(z)) dx∧dy + (x*y*z*cos(y) - y*z*cos(z)) dx∧dz - (x*cos(y) + y*sin(x))*z dy∧dz
Let us check the formula relating the exterior product to the tensor product for 1-forms:
sage: a.wedge(b) == a*b - b*a True
>>> from sage.all import * >>> a.wedge(b) == a*b - b*a True
The tensor product of a 1-form and a 2-form is not a 3-form but a tensor field of type \((0,3)\) with less symmetries:
sage: c = a*ab ; c Tensor field A⊗(A∧B) of type (0,3) on the 3-dimensional differentiable manifold R3 sage: c.symmetries() # the antisymmetry is only w.r.t. the last 2 arguments: no symmetry; antisymmetry: (1, 2) sage: d = ab*a ; d Tensor field (A∧B)⊗A of type (0,3) on the 3-dimensional differentiable manifold R3 sage: d.symmetries() # the antisymmetry is only w.r.t. the first 2 arguments: no symmetry; antisymmetry: (0, 1)
>>> from sage.all import * >>> c = a*ab ; c Tensor field A⊗(A∧B) of type (0,3) on the 3-dimensional differentiable manifold R3 >>> c.symmetries() # the antisymmetry is only w.r.t. the last 2 arguments: no symmetry; antisymmetry: (1, 2) >>> d = ab*a ; d Tensor field (A∧B)⊗A of type (0,3) on the 3-dimensional differentiable manifold R3 >>> d.symmetries() # the antisymmetry is only w.r.t. the first 2 arguments: no symmetry; antisymmetry: (0, 1)
The exterior derivative of a differential form is obtained by means of the method
exterior_derivative()
:sage: da = a.exterior_derivative() ; da 2-form dA on the 3-dimensional differentiable manifold R3 sage: da.display() dA = -(x + 1)*z dx∧dy - x*y dx∧dz + (x + z) dy∧dz sage: db = b.exterior_derivative() ; db 2-form dB on the 3-dimensional differentiable manifold R3 sage: db.display() dB = cos(x) dx∧dy + sin(z) dx∧dz - sin(y) dy∧dz sage: dab = ab.exterior_derivative() ; dab 3-form d(A∧B) on the 3-dimensional differentiable manifold R3
>>> from sage.all import * >>> da = a.exterior_derivative() ; da 2-form dA on the 3-dimensional differentiable manifold R3 >>> da.display() dA = -(x + 1)*z dx∧dy - x*y dx∧dz + (x + z) dy∧dz >>> db = b.exterior_derivative() ; db 2-form dB on the 3-dimensional differentiable manifold R3 >>> db.display() dB = cos(x) dx∧dy + sin(z) dx∧dz - sin(y) dy∧dz >>> dab = ab.exterior_derivative() ; dab 3-form d(A∧B) on the 3-dimensional differentiable manifold R3
or by applying the function
diff
to the differential form:sage: diff(a) is a.exterior_derivative() True
>>> from sage.all import * >>> diff(a) is a.exterior_derivative() True
As a 3-form over a 3-dimensional manifold,
d(A∧B)
is necessarily proportional to the volume 3-form:sage: dab == dab[[1,2,3]]/eps[[1,2,3]]*eps True
>>> from sage.all import * >>> dab == dab[[Integer(1),Integer(2),Integer(3)]]/eps[[Integer(1),Integer(2),Integer(3)]]*eps True
We may also check that the classical anti-derivation formula is fulfilled:
sage: dab == da.wedge(b) - a.wedge(db) True
>>> from sage.all import * >>> dab == da.wedge(b) - a.wedge(db) True
The Lie derivative of a 2-form is a 2-form:
sage: v = M.vector_field(y*z, -x*z, x*y, name='v') sage: ab.lie_der(v) # long time 2-form on the 3-dimensional differentiable manifold R3
>>> from sage.all import * >>> v = M.vector_field(y*z, -x*z, x*y, name='v') >>> ab.lie_der(v) # long time 2-form on the 3-dimensional differentiable manifold R3
Let us check Cartan formula, which expresses the Lie derivative in terms of exterior derivatives:
sage: ab.lie_der(v) == (v.contract(ab.exterior_derivative()) # long time ....: + v.contract(ab).exterior_derivative()) True
>>> from sage.all import * >>> ab.lie_der(v) == (v.contract(ab.exterior_derivative()) # long time ... + v.contract(ab).exterior_derivative()) True
A 1-form on a \(\RR^3\):
sage: om = M.one_form(name='omega', latex_name=r'\omega'); om 1-form omega on the 3-dimensional differentiable manifold R3
>>> from sage.all import * >>> om = M.one_form(name='omega', latex_name=r'\omega'); om 1-form omega on the 3-dimensional differentiable manifold R3
A 1-form is of course a differential form:
sage: isinstance(om, sage.manifolds.differentiable.diff_form.DiffFormParal) True sage: om.parent() Free module Omega^1(R3) of 1-forms on the 3-dimensional differentiable manifold R3 sage: om.tensor_type() (0, 1)
>>> from sage.all import * >>> isinstance(om, sage.manifolds.differentiable.diff_form.DiffFormParal) True >>> om.parent() Free module Omega^1(R3) of 1-forms on the 3-dimensional differentiable manifold R3 >>> om.tensor_type() (0, 1)
Setting the components with respect to the manifold’s default frame:
sage: om[:] = (2*z, x, x-y) sage: om[:] [2*z, x, x - y] sage: om.display() omega = 2*z dx + x dy + (x - y) dz
>>> from sage.all import * >>> om[:] = (Integer(2)*z, x, x-y) >>> om[:] [2*z, x, x - y] >>> om.display() omega = 2*z dx + x dy + (x - y) dz
A 1-form acts on vector fields:
sage: v = M.vector_field(x, 2*y, 3*z, name='V') sage: om(v) Scalar field omega(V) on the 3-dimensional differentiable manifold R3 sage: om(v).display() omega(V): R3 → ℝ (x, y, z) ↦ 2*x*y + (5*x - 3*y)*z (r, th, ph) ↦ 2*r^2*cos(ph)*sin(ph)*sin(th)^2 + r^2*(5*cos(ph) - 3*sin(ph))*cos(th)*sin(th) sage: latex(om(v)) \omega\left(V\right)
>>> from sage.all import * >>> v = M.vector_field(x, Integer(2)*y, Integer(3)*z, name='V') >>> om(v) Scalar field omega(V) on the 3-dimensional differentiable manifold R3 >>> om(v).display() omega(V): R3 → ℝ (x, y, z) ↦ 2*x*y + (5*x - 3*y)*z (r, th, ph) ↦ 2*r^2*cos(ph)*sin(ph)*sin(th)^2 + r^2*(5*cos(ph) - 3*sin(ph))*cos(th)*sin(th) >>> latex(om(v)) \omega\left(V\right)
The tensor product of two 1-forms is a tensor field of type \((0,2)\):
sage: a = M.one_form(1, 2, 3, name='A') sage: b = M.one_form(6, 5, 4, name='B') sage: c = a*b ; c Tensor field A⊗B of type (0,2) on the 3-dimensional differentiable manifold R3 sage: c[:] [ 6 5 4] [12 10 8] [18 15 12] sage: c.symmetries() # c has no symmetries: no symmetry; no antisymmetry
>>> from sage.all import * >>> a = M.one_form(Integer(1), Integer(2), Integer(3), name='A') >>> b = M.one_form(Integer(6), Integer(5), Integer(4), name='B') >>> c = a*b ; c Tensor field A⊗B of type (0,2) on the 3-dimensional differentiable manifold R3 >>> c[:] [ 6 5 4] [12 10 8] [18 15 12] >>> c.symmetries() # c has no symmetries: no symmetry; no antisymmetry
- derivative()[source]¶
Compute the exterior derivative of
self
.OUTPUT:
a
DiffFormParal
representing the exterior derivative of the differential form
EXAMPLES:
Exterior derivative of a 1-form on a 4-dimensional manifold:
sage: M = Manifold(4, 'M') sage: c_txyz.<t,x,y,z> = M.chart() sage: a = M.one_form(t*x*y*z, z*y**2, x*z**2, x**2 + y**2, name='A') sage: da = a.exterior_derivative() ; da 2-form dA on the 4-dimensional differentiable manifold M sage: da.display() dA = -t*y*z dt∧dx - t*x*z dt∧dy - t*x*y dt∧dz + (-2*y*z + z^2) dx∧dy + (-y^2 + 2*x) dx∧dz + (-2*x*z + 2*y) dy∧dz sage: latex(da) \mathrm{d}A
>>> from sage.all import * >>> M = Manifold(Integer(4), 'M') >>> c_txyz = M.chart(names=('t', 'x', 'y', 'z',)); (t, x, y, z,) = c_txyz._first_ngens(4) >>> a = M.one_form(t*x*y*z, z*y**Integer(2), x*z**Integer(2), x**Integer(2) + y**Integer(2), name='A') >>> da = a.exterior_derivative() ; da 2-form dA on the 4-dimensional differentiable manifold M >>> da.display() dA = -t*y*z dt∧dx - t*x*z dt∧dy - t*x*y dt∧dz + (-2*y*z + z^2) dx∧dy + (-y^2 + 2*x) dx∧dz + (-2*x*z + 2*y) dy∧dz >>> latex(da) \mathrm{d}A
The result is cached, i.e. is not recomputed unless
a
is changed:sage: a.exterior_derivative() is da True
>>> from sage.all import * >>> a.exterior_derivative() is da True
Instead of invoking the method
exterior_derivative()
, one may use the global functiondiff
:sage: diff(a) is a.exterior_derivative() True
>>> from sage.all import * >>> diff(a) is a.exterior_derivative() True
The exterior derivative is nilpotent:
sage: dda = da.exterior_derivative() ; dda 3-form ddA on the 4-dimensional differentiable manifold M sage: dda.display() ddA = 0 sage: dda == 0 True
>>> from sage.all import * >>> dda = da.exterior_derivative() ; dda 3-form ddA on the 4-dimensional differentiable manifold M >>> dda.display() ddA = 0 >>> dda == Integer(0) True
Let us check Cartan’s identity:
sage: v = M.vector_field(-y, x, t, z, name='v') sage: a.lie_der(v) == v.contract(diff(a)) + diff(a(v)) # long time True
>>> from sage.all import * >>> v = M.vector_field(-y, x, t, z, name='v') >>> a.lie_der(v) == v.contract(diff(a)) + diff(a(v)) # long time True
- exterior_derivative()[source]¶
Compute the exterior derivative of
self
.OUTPUT:
a
DiffFormParal
representing the exterior derivative of the differential form
EXAMPLES:
Exterior derivative of a 1-form on a 4-dimensional manifold:
sage: M = Manifold(4, 'M') sage: c_txyz.<t,x,y,z> = M.chart() sage: a = M.one_form(t*x*y*z, z*y**2, x*z**2, x**2 + y**2, name='A') sage: da = a.exterior_derivative() ; da 2-form dA on the 4-dimensional differentiable manifold M sage: da.display() dA = -t*y*z dt∧dx - t*x*z dt∧dy - t*x*y dt∧dz + (-2*y*z + z^2) dx∧dy + (-y^2 + 2*x) dx∧dz + (-2*x*z + 2*y) dy∧dz sage: latex(da) \mathrm{d}A
>>> from sage.all import * >>> M = Manifold(Integer(4), 'M') >>> c_txyz = M.chart(names=('t', 'x', 'y', 'z',)); (t, x, y, z,) = c_txyz._first_ngens(4) >>> a = M.one_form(t*x*y*z, z*y**Integer(2), x*z**Integer(2), x**Integer(2) + y**Integer(2), name='A') >>> da = a.exterior_derivative() ; da 2-form dA on the 4-dimensional differentiable manifold M >>> da.display() dA = -t*y*z dt∧dx - t*x*z dt∧dy - t*x*y dt∧dz + (-2*y*z + z^2) dx∧dy + (-y^2 + 2*x) dx∧dz + (-2*x*z + 2*y) dy∧dz >>> latex(da) \mathrm{d}A
The result is cached, i.e. is not recomputed unless
a
is changed:sage: a.exterior_derivative() is da True
>>> from sage.all import * >>> a.exterior_derivative() is da True
Instead of invoking the method
exterior_derivative()
, one may use the global functiondiff
:sage: diff(a) is a.exterior_derivative() True
>>> from sage.all import * >>> diff(a) is a.exterior_derivative() True
The exterior derivative is nilpotent:
sage: dda = da.exterior_derivative() ; dda 3-form ddA on the 4-dimensional differentiable manifold M sage: dda.display() ddA = 0 sage: dda == 0 True
>>> from sage.all import * >>> dda = da.exterior_derivative() ; dda 3-form ddA on the 4-dimensional differentiable manifold M >>> dda.display() ddA = 0 >>> dda == Integer(0) True
Let us check Cartan’s identity:
sage: v = M.vector_field(-y, x, t, z, name='v') sage: a.lie_der(v) == v.contract(diff(a)) + diff(a(v)) # long time True
>>> from sage.all import * >>> v = M.vector_field(-y, x, t, z, name='v') >>> a.lie_der(v) == v.contract(diff(a)) + diff(a(v)) # long time True
- interior_product(qvect)[source]¶
Interior product with a multivector field.
If
self
is a differential form \(A\) of degree \(p\) and \(B\) is a multivector field of degree \(q\geq p\) on the same manifold, the interior product of \(A\) by \(B\) is the multivector field \(\iota_A B\) of degree \(q-p\) defined by\[(\iota_A B)^{i_1\ldots i_{q-p}} = A_{k_1\ldots k_p} B^{k_1\ldots k_p i_1\ldots i_{q-p}}\]Note
A.interior_product(B)
yields the same result asA.contract(0,..., p-1, B, 0,..., p-1)
(cf.contract()
), butinterior_product
is more efficient, the alternating character of \(A\) being not used to reduce the computation incontract()
INPUT:
qvect
– multivector field \(B\) (instance ofMultivectorFieldParal
); the degree of \(B\) must be at least equal to the degree ofself
OUTPUT:
scalar field (case \(p=q\)) or
MultivectorFieldParal
(case \(p<q\)) representing the interior product \(\iota_A B\), where \(A\) isself
See also
interior_product()
for the interior product of a multivector field with a differential formEXAMPLES:
Interior product of a 1-form with a 2-vector field on a 3-dimensional manifold:
sage: M = Manifold(3, 'M', start_index=1) sage: X.<x,y,z> = M.chart() sage: a = M.one_form(2, 1+x, y*z, name='a') sage: b = M.multivector_field(2, name='b') sage: b[1,2], b[1,3], b[2,3] = y^2, z+x, -z^2 sage: s = a.interior_product(b); s Vector field i_a b on the 3-dimensional differentiable manifold M sage: s.display() i_a b = (-(x + 1)*y^2 - x*y*z - y*z^2) ∂/∂x + (y*z^3 + 2*y^2) ∂/∂y + (-(x + 1)*z^2 + 2*x + 2*z) ∂/∂z sage: s == a.contract(b) True
>>> from sage.all import * >>> M = Manifold(Integer(3), 'M', start_index=Integer(1)) >>> X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3) >>> a = M.one_form(Integer(2), Integer(1)+x, y*z, name='a') >>> b = M.multivector_field(Integer(2), name='b') >>> b[Integer(1),Integer(2)], b[Integer(1),Integer(3)], b[Integer(2),Integer(3)] = y**Integer(2), z+x, -z**Integer(2) >>> s = a.interior_product(b); s Vector field i_a b on the 3-dimensional differentiable manifold M >>> s.display() i_a b = (-(x + 1)*y^2 - x*y*z - y*z^2) ∂/∂x + (y*z^3 + 2*y^2) ∂/∂y + (-(x + 1)*z^2 + 2*x + 2*z) ∂/∂z >>> s == a.contract(b) True
Interior product of a 2-form with a 2-vector field:
sage: a = M.diff_form(2, name='a') sage: a[1,2], a[1,3], a[2,3] = x*y, -3, z sage: s = a.interior_product(b); s Scalar field i_a b on the 3-dimensional differentiable manifold M sage: s.display() i_a b: M → ℝ (x, y, z) ↦ 2*x*y^3 - 2*z^3 - 6*x - 6*z sage: s == a.contract(0,1,b,0,1) True
>>> from sage.all import * >>> a = M.diff_form(Integer(2), name='a') >>> a[Integer(1),Integer(2)], a[Integer(1),Integer(3)], a[Integer(2),Integer(3)] = x*y, -Integer(3), z >>> s = a.interior_product(b); s Scalar field i_a b on the 3-dimensional differentiable manifold M >>> s.display() i_a b: M → ℝ (x, y, z) ↦ 2*x*y^3 - 2*z^3 - 6*x - 6*z >>> s == a.contract(Integer(0),Integer(1),b,Integer(0),Integer(1)) True
- wedge(other)[source]¶
Exterior product of
self
with another differential form.INPUT:
other
– another differential form
OUTPUT:
instance of
DiffFormParal
representing the exterior productself ∧ other
EXAMPLES:
Exterior product of a 1-form and a 2-form on a 3-dimensional manifold:
sage: M = Manifold(3, 'M', start_index=1) sage: X.<x,y,z> = M.chart() sage: a = M.one_form(2, 1+x, y*z, name='a') sage: b = M.diff_form(2, name='b') sage: b[1,2], b[1,3], b[2,3] = y^2, z+x, z^2 sage: a.display() a = 2 dx + (x + 1) dy + y*z dz sage: b.display() b = y^2 dx∧dy + (x + z) dx∧dz + z^2 dy∧dz sage: s = a.wedge(b); s 3-form a∧b on the 3-dimensional differentiable manifold M sage: s.display() a∧b = (-x^2 + (y^3 - x - 1)*z + 2*z^2 - x) dx∧dy∧dz
>>> from sage.all import * >>> M = Manifold(Integer(3), 'M', start_index=Integer(1)) >>> X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3) >>> a = M.one_form(Integer(2), Integer(1)+x, y*z, name='a') >>> b = M.diff_form(Integer(2), name='b') >>> b[Integer(1),Integer(2)], b[Integer(1),Integer(3)], b[Integer(2),Integer(3)] = y**Integer(2), z+x, z**Integer(2) >>> a.display() a = 2 dx + (x + 1) dy + y*z dz >>> b.display() b = y^2 dx∧dy + (x + z) dx∧dz + z^2 dy∧dz >>> s = a.wedge(b); s 3-form a∧b on the 3-dimensional differentiable manifold M >>> s.display() a∧b = (-x^2 + (y^3 - x - 1)*z + 2*z^2 - x) dx∧dy∧dz
Check:
sage: s[1,2,3] == a[1]*b[2,3] + a[2]*b[3,1] + a[3]*b[1,2] True
>>> from sage.all import * >>> s[Integer(1),Integer(2),Integer(3)] == a[Integer(1)]*b[Integer(2),Integer(3)] + a[Integer(2)]*b[Integer(3),Integer(1)] + a[Integer(3)]*b[Integer(1),Integer(2)] True
Wedging with scalar fields yields the multiplication from right:
sage: f = M.scalar_field(x, name='f') sage: t = a.wedge(f) sage: t.display() f*a = 2*x dx + (x^2 + x) dy + x*y*z dz
>>> from sage.all import * >>> f = M.scalar_field(x, name='f') >>> t = a.wedge(f) >>> t.display() f*a = 2*x dx + (x^2 + x) dy + x*y*z dz