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.
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 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)¶ 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 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 nonparallelizable 2dimensional 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, xy), 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 2form a on the 2dimensional differentiable manifold M sage: a.parent() Module Omega^2(M) of 2forms on the 2dimensional 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 1form on
M
:sage: a = M.one_form('a') ; a 1form a on the 2dimensional differentiable manifold M sage: a.parent() Module Omega^1(M) of 1forms on the 2dimensional differentiable manifold M sage: a.degree() 1
Setting the components of the 1form 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 1form is a 2form:
sage: da = a.exterior_derivative() ; da 2form da on the 2dimensional differentiable manifold M sage: da.display(eU) da = 2 dx/\dy sage: da.display(eV) da = du/\dv
Another 1form:
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 1forms results in another 1form:
sage: s = a + b ; s 1form a+b on the 2dimensional 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 1forms is a 2form:
sage: s = a.wedge(b) ; s 2form a/\b on the 2dimensional 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 1form by a scalar field results in another 1form:
sage: f = M.scalar_field({c_xy: (x+y)^2, c_uv: u^2}, name='f') sage: s = f*a ; s 1form on the 2dimensional 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 2form on the 3dimensional differentiable manifold M sage: a.degree() 2 sage: b = M.diff_form(1); b 1form on the 3dimensional 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 1form on the 2sphere:
sage: M = Manifold(2, 'M') # the 2dimensional 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 1form:
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 2form da on the 2dimensional 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 functionexterior_derivative()
or its aliasxder()
: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
 instance of

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 pseudoRiemannian metric \(g\) is the \((np)\)form \(*A\) defined by
\[*A_{i_1\ldots i_{np}} = \frac{1}{p!} A_{k_1\ldots k_p} \epsilon^{k_1\ldots k_p}_{\qquad\ i_1\ldots i_{np}}\]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 pseudoRiemannian metric defined on the same manifold as the current differential form; must be an instance ofPseudoRiemannianMetric
OUTPUT:
 the \((np)\)form \(*A\)
EXAMPLES:
Hodge dual of a 1form on the 2sphere 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 1form 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 1form *a on the 2dimensional 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 methodhodge_star()
of the metric:sage: a.hodge_dual(g) == g.hodge_star(a) True
For a 1form and a Riemannian metric in dimension 2, the Hodge dual applied twice is minus the identity:
sage: ssa = sa.hodge_dual(g); ssa 1form **a on the 2dimensional differentiable manifold S^2 sage: ssa == a True
The Hodge dual of the metric volume 2form is the constant scalar field 1 (considered as a 0form):
sage: eps = g.volume_form(); eps 2form eps_g on the 2dimensional 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 2dimensional 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 \(qp\) defined by\[(\iota_A B)^{i_1\ldots i_{qp}} = A_{k_1\ldots k_p} B^{k_1\ldots k_p i_1\ldots i_{qp}}\]Note
A.interior_product(B)
yields the same result asA.contract(0,..., p1, B, 0,..., p1)
(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 1form with a 2vector field on the 2sphere:
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 2dimensional 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 2form with a 2vector 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 2form 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 2dimensional 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 productself/\other
EXAMPLES:
Exterior product of two 1forms on the 2sphere:
sage: M = Manifold(2, 'S^2', start_index=1) # the 2dimensional 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 2form a/\b on the 2dimensional 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 formlatex_name
– (default:None
) LaTeX symbol to denote the differential form; if none is provided, the LaTeX symbol is set toname
EXAMPLES:
A 2form on a 4dimensional manifold:
sage: M = Manifold(4, 'M') sage: c_txyz.<t,x,y,z> = M.chart() sage: a = M.diff_form(2, 'a') ; a 2form a on the 4dimensional differentiable manifold M sage: a.parent() Free module Omega^2(M) of 2forms on the 4dimensional 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 2indices 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 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
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 2form on the 4dimensional 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 2form on the 4dimensional differentiable manifold M sage: s[:] [ 0 1 2 3] [1 0 3 0] [ 2 3 0 0] [ 3 0 0 0]
An example of 3form 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 changeofframe 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 3indices 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 2form A/\B on the 3dimensional 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 1forms:
sage: a.wedge(b) == a*b  b*a True
The tensor product of a 1form and a 2form is not a 3form 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 3dimensional 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 3dimensional 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 2form dA on the 3dimensional 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 2form dB on the 3dimensional 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 3form d(A/\B) on the 3dimensional differentiable manifold R3
As a 3form over a 3dimensional manifold,
d(A/\B)
is necessarily proportional to the volume 3form:sage: dab == dab[[1,2,3]]/eps[[1,2,3]]*eps True
We may also check that the classical antiderivation formula is fulfilled:
sage: dab == da.wedge(b)  a.wedge(db) True
The Lie derivative of a 2form is a 2form:
sage: v = M.vector_field('v') sage: v[:] = (y*z, x*z, x*y) sage: ab.lie_der(v) # long time 2form on the 3dimensional 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 1form on a \(\RR^3\):
sage: om = M.one_form('omega', r'\omega') ; om 1form omega on the 3dimensional differentiable manifold R3
A 1form 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 1forms on the 3dimensional 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, xy) sage: om[:] [2*z, x, x  y] sage: om.display() omega = 2*z dx + x dy + (x  y) dz
A 1form 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 3dimensional 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 1forms 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 3dimensional 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 1form on a 4dimensional 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 2form dA on the 4dimensional 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 functionexterior_derivative()
or its aliasxder()
: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 3form ddA on the 4dimensional 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
 a

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 pseudoRiemannian metric \(g\) is the \((np)\)form \(*A\) defined by
\[*A_{i_1\ldots i_{np}} = \frac{1}{p!} A_{k_1\ldots k_p} \epsilon^{k_1\ldots k_p}_{\qquad\ i_1\ldots i_{np}}\]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 pseudoRiemannian metric defined on the same manifold as the current differential form; must be an instance ofPseudoRiemannianMetric
OUTPUT:
 the \((np)\)form \(*A\)
EXAMPLES:
Hodge dual of a 1form 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 2form *A on the 3dimensional differentiable manifold M sage: sa.display() *A = Az dx/\dy  Ay dx/\dz + Ax dy/\dz sage: ssa = sa.hodge_dual(g) ; ssa 1form **A on the 3dimensional 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 methodhodge_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 \(qp\) defined by\[(\iota_A B)^{i_1\ldots i_{qp}} = A_{k_1\ldots k_p} B^{k_1\ldots k_p i_1\ldots i_{qp}}\]Note
A.interior_product(B)
yields the same result asA.contract(0,..., p1, B, 0,..., p1)
(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 1form with a 2vector field on a 3dimensional 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 3dimensional 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 2form with a 2vector 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 3dimensional 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 productself/\other
EXAMPLES:
Exterior product of a 1form and a 2form on a 3dimensional 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 3form a/\b on the 3dimensional 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