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:

Note

A difference with the class DifferentialForm is that the present classes lie at the tensor field level. Accordingly, an instance of DiffForm or DiffFormParal can have various sets of components, each in a different coordinate system (or more generally in a different coframe), while the class DifferentialForm considers differential forms at the component level in a fixed chart. In this respect, the class DifferentialForm is closer to the class CompFullyAntiSym than to DiffForm.

AUTHORS:

  • Eric Gourgoulhon, Michal Bejger (2013, 2014): initial version
  • Joris Vankerschaver (2010): developed a previous class, DifferentialForm (cf. the above note), which inspired the storage of the non-zero 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)

Bases: sage.manifolds.differentiable.tensorfield.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 form
  • latex_name – (default: None) LaTeX symbol to denote the differential form; if none is provided, the LaTeX symbol is set to name

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

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

A 1-form on M:

sage: a = M.one_form('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

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

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

Another 1-form:

sage: b = M.one_form('b')
sage: b[eU,:] = [1+x*y, x^2]
sage: 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

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

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 on the 2-dimensional differentiable manifold M
sage: s.display(eU)
(-x^2*y - 2*x*y^2 - y^3) dx + (x^3 + 2*x^2*y + x*y^2) dy
sage: s.display(eV)
1/2*u^2*v du - 1/2*u^3 dv
degree()

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
exterior_derivative()

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()

The 1-form:

sage: a = M.diff_form(1, name='a')
sage: a[e_xy,:] = -y^2, x^2
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

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

The result is cached, i.e. is not recomputed unless a is changed:

sage: a.exterior_derivative() is da
True

Instead of invoking the method exterior_derivative(), one may use the global function exterior_derivative() or its alias xder():

sage: from sage.manifolds.utilities import xder
sage: xder(a) is a.exterior_derivative()
True

Let us check Cartan’s identity:

sage: v = M.vector_field(name='v')
sage: v[e_xy, :] = -y, x
sage: v.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
sage: a.lie_der(v) == v.contract(xder(a)) + xder(a(v))  # long time
True
hodge_dual(metric)

Compute the Hodge dual of the differential form with respect to some metric.

If the differential form is a \(p\)-form \(A\), its Hodge dual with respect to a pseudo-Riemannian metric \(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}_{\qquad\ 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\).

INPUT:

  • metric: a pseudo-Riemannian metric defined on the same manifold as the current differential form; must be an instance of PseudoRiemannianMetric

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

Then we construct the 1-form and take its Hodge dual w.r.t. \(g\):

sage: a = M.one_form(name='a')
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 = -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

Instead of calling the method hodge_dual() on the differential form, one can invoke the method hodge_star() of the metric:

sage: 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

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 --> R
on U: (x, y) |--> 1
on V: (u, v) |--> 1
interior_product(qvect)

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 as A.contract(0,..., p-1, B, 0,..., p-1) (cf. contract()), but interior_product is more efficient, the alternating character of \(A\) being not used to reduce the computation in contract()

INPUT:

  • qvect – multivector field \(B\) (instance of MultivectorField); the degree of \(B\) must be at least equal to the degree of self

OUTPUT:

  • scalar field (case \(p=q\)) or MultivectorField (case \(p<q\)) representing the interior product \(\iota_A B\), where \(A\) is self

See also

interior_product() for the interior product of a multivector field with a differential form

EXAMPLES:

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(name='a')
sage: a[e_xy,:] = y, x
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 d/dx + x*y^2 d/dy
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) d/du
 + (3*u^3*v^2 - u*v^4)/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6) d/dv
sage: 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 --> R
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
wedge(other)

Exterior product with another differential form.

INPUT:

  • other – another differential form (on the same manifold)

OUTPUT:

  • instance of DiffForm representing the exterior product self/\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.diff_form(1, name='a')
sage: a[e_xy,:] = y, x
sage: a.add_comp_by_continuation(e_uv, W, c_uv)
sage: b = M.diff_form(1, name='b')
sage: b[e_xy,:] = x^2 + y^2, y
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
class sage.manifolds.differentiable.diff_form.DiffFormParal(vector_field_module, degree, name=None, latex_name=None)

Bases: sage.tensor.modules.free_module_alt_form.FreeModuleAltForm, sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal

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 form
  • latex_name – (default: None) LaTeX symbol to denote the differential form; if none is provided, the LaTeX symbol is set to name

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, '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

A differential form is a tensor field of purely covariant type:

sage: 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, (d/dt,d/dx,d/dy,d/dz))
sage: type(a.comp())
<class 'sage.tensor.modules.comp.CompFullyAntiSym'>

Setting a component with repeated indices to a non-zero 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

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

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]

An example of 3-form is the volume element on \(\RR^3\) in Cartesian coordinates:

sage: M = Manifold(3, 'R3', '\RR^3', start_index=1)
sage: c_cart.<x,y,z> = M.chart()
sage: eps = M.diff_form(3, 'epsilon', 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

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))
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, (d/dr,d/dth,d/dph))
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

The exterior product of two differential forms is performed via the method wedge():

sage: a = M.one_form('A')
sage: a[:] = (x*y*z, -z*x, y*z)
sage: b = M.one_form('B')
sage: b[:] = (cos(z), sin(x), cos(y))
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

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

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)

The exterior derivative of a differential form is obtained by means of the 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

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

We may also check that the classical anti-derivation formula is fulfilled:

sage: dab == da.wedge(b) - a.wedge(db)
True

The Lie derivative of a 2-form is a 2-form:

sage: v = M.vector_field('v')
sage: v[:] = (y*z, -x*z, x*y)
sage: 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

A 1-form on a \(\RR^3\):

sage: om = M.one_form('omega', 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)

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

A 1-form acts on vector fields:

sage: v = M.vector_field('V')
sage: v[:] = (x, 2*y, 3*z)
sage: om(v)
Scalar field omega(V) on the 3-dimensional differentiable manifold R3
sage: om(v).display()
omega(V): R3 --> R
   (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)

The tensor product of two 1-forms is a tensor field of type \((0,2)\):

sage: a = M.one_form('A')
sage: a[:] = (1, 2, 3)
sage: b = M.one_form('B')
sage: b[:] = (6, 5, 4)
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
exterior_derivative()

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('A')
sage: a[:] = (t*x*y*z, z*y**2, x*z**2, x**2 + y**2)
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

The result is cached, i.e. is not recomputed unless a is changed:

sage: a.exterior_derivative() is da
True

Instead of invoking the method exterior_derivative(), one may use the global function exterior_derivative() or its alias xder():

sage: from sage.manifolds.utilities import xder
sage: xder(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

Let us check Cartan’s identity:

sage: v = M.vector_field(name='v')
sage: v[:] = -y, x, t, z
sage: a.lie_der(v) == v.contract(xder(a)) + xder(a(v)) # long time
True
hodge_dual(metric)

Compute the Hodge dual of the differential form with respect to some metric.

If the differential form is a \(p\)-form \(A\), its Hodge dual with respect to a pseudo-Riemannian metric \(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}_{\qquad\ 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\).

INPUT:

  • metric: a pseudo-Riemannian metric defined on the same manifold as the current differential form; must be an instance of PseudoRiemannianMetric

OUTPUT:

  • the \((n-p)\)-form \(*A\)

EXAMPLES:

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: a = M.one_form('A')
sage: var('Ax Ay Az')
(Ax, Ay, Az)
sage: a[:] = (Ax, Ay, Az)
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

Instead of calling the method hodge_dual() on the differential form, one can invoke the method hodge_star() of the metric:

sage: a.hodge_dual(g) == g.hodge_star(a)
True

See the documentation of hodge_star() for more examples.

interior_product(qvect)

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 as A.contract(0,..., p-1, B, 0,..., p-1) (cf. contract()), but interior_product is more efficient, the alternating character of \(A\) being not used to reduce the computation in contract()

INPUT:

  • qvect – multivector field \(B\) (instance of MultivectorFieldParal); the degree of \(B\) must be at least equal to the degree of self

OUTPUT:

  • scalar field (case \(p=q\)) or MultivectorFieldParal (case \(p<q\)) representing the interior product \(\iota_A B\), where \(A\) is self

See also

interior_product() for the interior product of a multivector field with a differential form

EXAMPLES:

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(name='a')
sage: a[:] = [2, 1+x, y*z]
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) d/dx
 + (y*z^3 + 2*y^2) d/dy + (-(x + 1)*z^2 + 2*x + 2*z) d/dz
sage: 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 --> R
   (x, y, z) |--> 2*x*y^3 - 2*z^3 - 6*x - 6*z
sage: s == a.contract(0,1,b,0,1)
True
wedge(other)

Exterior product of self with another differential form.

INPUT:

  • other – another differential form

OUTPUT:

  • instance of DiffFormParal representing the exterior product self/\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(name='a')
sage: a[:] = [2, 1+x, y*z]
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

Check:

sage: s[1,2,3] == a[1]*b[2,3] + a[2]*b[3,1] + a[3]*b[1,2]
True