Ask Your Question

Revision history [back]

I would advise to use the manifold version: all the functionalities of the CoordinatePatch version are available in the manifold version and the latter is more recent and provides more functionalities, like

  • changing the coordinates
  • evaluating the Lie derivative with respect to a vector field
  • performing the interior product with a p-vector
  • evaluating the Hodge dual with respect to a metric

It is also more flexible:

  • the indices may be chosen to start from 1 instead of 0
  • one may use index notation with summation on repeated indices.

The two versions cannot be mixed and most probably the CoordinatePatch version should be deprecated.

1. Illustration of similarities and differences

Let us declare a differential form of degree 2 with the CoordinatePatch version:

sage: x, y, z = var('x, y, z')
sage: U = CoordinatePatch((x, y, z))
sage: F = DifferentialForms(U)
sage: f = DifferentialForm(F, 2)
sage: f[0,1] = x*sin(z)
sage: f[1,2] = y*z
sage: f
x*sin(z)*dx/\dy + y*z*dy/\dz

To perform the same thing with the manifold version, one should write (using a different Sage session to avoid any confusion):

sage: U = Manifold(3, 'U')
sage: X.<x,y,z> = U.chart()
sage: f = U.diff_form(2, 'f')
sage: f[0,1] = x*sin(z)
sage: f[1,2] = y*z
sage: f
2-form f on the 3-dimensional differentiable manifold U
sage: f.display()
f = x*sin(z) dx/\dy + y*z dy/\dz

Let us introduce another differential form, as a 1-form; in the CoordinatePatch version:

sage: g = DifferentialForm(F, 1)
sage: g[0], g[1], g[2] = (y^2, -z, 2*x-y)
sage: g
(2*x - y)*dz + y^2*dx + -z*dy

In the manifold version, one may use the shortcut notation g[:] to set the components of g:

sage: g = U.diff_form(1, 'g')
sage: g[:] = (y^2, -z, 2*x-y)
sage: g.display()
g = y^2 dx - z dy + (2*x - y) dz

The wedge product of f by g is obtained in the same way in both methods: for CoordinatePatch:

sage: f.wedge(g)
(y^3*z + (2*x - y)*x*sin(z))*dx/\dy/\dz

while for the manifold version:

sage: f.wedge(g)
3-form f/\g on the 3-dimensional differentiable manifold U
sage: f.wedge(g).display()
f/\g = (y^3*z + (2*x^2 - x*y)*sin(z)) dx/\dy/\dz

The exterior derivative is computed via the method diff() in the CoordinatePatch version:

sage: f.diff()
x*cos(z)*dx/\dy/\dz

and via the method exterior_derivative() in the manifold version:

sage: f.exterior_derivative().display()
df = x*cos(z) dx/\dy/\dz

A shortcut is provided by the function xder, to be used as the operator $\mathrm{d}$ to compute $\mathrm{d}f$:

sage: from sage.manifolds.utilities import xder
sage: xder(f) == f.exterior_derivative()
True

A difference regards the parents: in the CoordinatePatch version, the 2-form f and the 1-form g have the same parent, which is the graded algebra $\Omega(U)$ of all differential forms defined on $U$, and declared as F = DifferentialForms(U) at the beginning ot the session:

sage: f.parent()
Algebra of differential forms in the variables x, y, z
sage: f.parent() is F
True
sage: g.parent() is F
True

In the manifold case, the parent of f is the set $\Omega^2(U)$ of 2-forms on $U$, which is considered as a free module of rank 3 on the algebra $C^\infty(U)$ of scalar fields on $U$, while the parent of g is the set $\Omega^1(U)$ of 1-forms on $U$, which is considered as another free module of rank 3 on $C^\infty(U)$:

sage: f.parent()
Free module Omega^2(U) of 2-forms on the 3-dimensional differentiable manifold U
sage: f.parent().base_ring()
Algebra of differentiable scalar fields on the 3-dimensional differentiable manifold U
sage: f.parent().rank()
3
sage: g.parent()
Free module Omega^1(U) of 1-forms on the 3-dimensional differentiable manifold U
sage: g.parent().rank()
3

2. Examples of functionalities avalaible only in the manifold version

The capability to access directly to the coordinate basis 1-forms:

sage: X.coframe()
Coordinate coframe (U, (dx,dy,dz))
sage: dx = X.coframe()[0]
sage: dy = X.coframe()[1]
sage: a = sin(z)*dx.wedge(dy)
sage: a.display()
sin(z) dx/\dy

The interior product with a vector field:

sage: v = U.vector_field('v')
sage: v[:] = (-y, z, x^2)
sage: v.interior_product(f)
1-form i_v f on the 3-dimensional differentiable manifold U
sage: v.interior_product(f).display()
i_v f = -x*z*sin(z) dx + (-x^2*y*z - x*y*sin(z)) dy + y*z^2 dz

The Lie derivative with respect to a vector field:

sage: f.lie_derivative(v)
2-form on the 3-dimensional differentiable manifold U
sage: f.lie_derivative(v).display()
(x^3*cos(z) - 2*x*y*z - y*sin(z)) dx/\dy + x*sin(z) dx/\dz + (x^2*y + z^2) dy/\dz

As an illustration, we may check that Cartan identity $\mathcal{L}_v f = \mathrm{d}(\iota_v f) + \iota_v \mathrm{d} f $ holds:

sage: f.lie_derivative(v) == (v.interior_product(f)).exterior_derivative() + \
....:                        v.interior_product(f.exterior_derivative())
True

Computing the Hodge dual with respect to a given metric:

sage: h = U.metric('h')
sage: h[0,0] = 1+y^2
sage: h[1,1] = 1+z^2
sage: h[2,2] = 1+x^2
sage: h.display()
h = (y^2 + 1) dx*dx + (z^2 + 1) dy*dy + (x^2 + 1) dz*dz
sage: f.hodge_dual(h)
1-form *f on the 3-dimensional differentiable manifold U
sage: f.hodge_dual(h).display()
*f = sqrt(y^2 + 1)*y*z/(sqrt(x^2 + 1)*sqrt(z^2 + 1)) dx + sqrt(x^2 + 1)*x*sin(z)/(sqrt(y^2 + 1)*sqrt(z^2 + 1)) dz

Computing new components under a change of coordinates:

sage: X2.<u,v,w> = U.chart()
sage: X_to_X2 = X.transition_map(X2, [y+z, z+x, x+y])
sage: X_to_X2.inverse()
Change of coordinates from Chart (U, (u, v, w)) to Chart (U, (x, y, z))
sage: g.display()  # the default for g.display(X.frame(), X)
g = y^2 dx - z dy + (2*x - y) dz
sage: g.display(X2.frame(), X2)
g = (-1/8*u^2 + 1/4*(u + 2)*v - 1/8*v^2 - 1/4*(u - v - 2)*w - 1/8*w^2 - u) du + (1/8*u^2 - 1/4*(u - 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 - 1/2*u) dv + (1/8*u^2 - 1/4*(u + 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 + 1/2*u) dw

Using the function display_comp, which is more convenient for lengthy expressions:

sage: g.display_comp()   # the default for g.display_comp(X.frame(), X)
g_x = y^2 
g_y = -z 
g_z = 2*x - y 
sage: g.display_comp(X2.frame(), X2)
g_u = -1/8*u^2 + 1/4*(u + 2)*v - 1/8*v^2 - 1/4*(u - v - 2)*w - 1/8*w^2 - u 
g_v = 1/8*u^2 - 1/4*(u - 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 - 1/2*u 
g_w = 1/8*u^2 - 1/4*(u + 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 + 1/2*u

I would advise to use the manifold version: all the functionalities of the CoordinatePatch version are available in the manifold version and version, but the latter is more recent and provides more functionalities, like

  • changing the coordinates
  • evaluating the Lie derivative with respect to a vector field
  • performing the interior product with a p-vector
  • evaluating the Hodge dual with respect to a metric

It is also more flexible:

  • the indices may be chosen to start from 1 instead of 0
  • one may use index notation with summation on repeated indices.

The two versions cannot be mixed and most probably the CoordinatePatch version should be deprecated.

1. Illustration of similarities and differences

Let us declare a differential form of degree 2 with the CoordinatePatch version:

sage: x, y, z = var('x, y, z')
sage: U = CoordinatePatch((x, y, z))
sage: F = DifferentialForms(U)
sage: f = DifferentialForm(F, 2)
sage: f[0,1] = x*sin(z)
sage: f[1,2] = y*z
sage: f
x*sin(z)*dx/\dy + y*z*dy/\dz

To perform the same thing with the manifold version, one should write (using a different Sage session to avoid any confusion):

sage: U = Manifold(3, 'U')
sage: X.<x,y,z> = U.chart()
sage: f = U.diff_form(2, 'f')
sage: f[0,1] = x*sin(z)
sage: f[1,2] = y*z
sage: f
2-form f on the 3-dimensional differentiable manifold U
sage: f.display()
f = x*sin(z) dx/\dy + y*z dy/\dz

Let us introduce another differential form, as a 1-form; in the CoordinatePatch version:

sage: g = DifferentialForm(F, 1)
sage: g[0], g[1], g[2] = (y^2, -z, 2*x-y)
sage: g
(2*x - y)*dz + y^2*dx + -z*dy

In the manifold version, one may use the shortcut notation g[:] to set the components of g:

sage: g = U.diff_form(1, 'g')
sage: g[:] = (y^2, -z, 2*x-y)
sage: g.display()
g = y^2 dx - z dy + (2*x - y) dz

The wedge product of f by g is obtained in the same way in both methods: for CoordinatePatch:

sage: f.wedge(g)
(y^3*z + (2*x - y)*x*sin(z))*dx/\dy/\dz

while for the manifold version:

sage: f.wedge(g)
3-form f/\g on the 3-dimensional differentiable manifold U
sage: f.wedge(g).display()
f/\g = (y^3*z + (2*x^2 - x*y)*sin(z)) dx/\dy/\dz

The exterior derivative is computed via the method diff() in the CoordinatePatch version:

sage: f.diff()
x*cos(z)*dx/\dy/\dz

and via the method exterior_derivative() in the manifold version:

sage: f.exterior_derivative().display()
df = x*cos(z) dx/\dy/\dz

A shortcut is provided by the function xder, to be used as the operator $\mathrm{d}$ to compute $\mathrm{d}f$:

sage: from sage.manifolds.utilities import xder
sage: xder(f) == f.exterior_derivative()
True

A difference regards the parents: in the CoordinatePatch version, the 2-form f and the 1-form g have the same parent, which is the graded algebra $\Omega(U)$ of all differential forms defined on $U$, and declared as F = DifferentialForms(U) at the beginning ot of the session:

sage: f.parent()
Algebra of differential forms in the variables x, y, z
sage: f.parent() is F
True
sage: g.parent() is F
True

In the manifold case, the parent of f is the set $\Omega^2(U)$ of 2-forms on $U$, which is considered as a free module of rank 3 on the algebra $C^\infty(U)$ of scalar fields on $U$, while the parent of g is the set $\Omega^1(U)$ of 1-forms on $U$, which is considered as another free module of rank 3 on $C^\infty(U)$:

sage: f.parent()
Free module Omega^2(U) of 2-forms on the 3-dimensional differentiable manifold U
sage: f.parent().base_ring()
Algebra of differentiable scalar fields on the 3-dimensional differentiable manifold U
sage: f.parent().rank()
3
sage: g.parent()
Free module Omega^1(U) of 1-forms on the 3-dimensional differentiable manifold U
sage: g.parent().rank()
3

2. Examples of functionalities avalaible only in the manifold version

The capability to access directly to the coordinate basis 1-forms:

sage: X.coframe()
Coordinate coframe (U, (dx,dy,dz))
sage: dx = X.coframe()[0]
sage: dy = X.coframe()[1]
sage: a = sin(z)*dx.wedge(dy)
sage: a.display()
sin(z) dx/\dy

The interior product with a vector field:

sage: v = U.vector_field('v')
sage: v[:] = (-y, z, x^2)
sage: v.interior_product(f)
1-form i_v f on the 3-dimensional differentiable manifold U
sage: v.interior_product(f).display()
i_v f = -x*z*sin(z) dx + (-x^2*y*z - x*y*sin(z)) dy + y*z^2 dz

The Lie derivative with respect to a vector field:

sage: f.lie_derivative(v)
2-form on the 3-dimensional differentiable manifold U
sage: f.lie_derivative(v).display()
(x^3*cos(z) - 2*x*y*z - y*sin(z)) dx/\dy + x*sin(z) dx/\dz + (x^2*y + z^2) dy/\dz

As an illustration, we may check that Cartan Cartan's identity $\mathcal{L}_v f = \mathrm{d}(\iota_v f) + \iota_v \mathrm{d} f $ holds:

sage: f.lie_derivative(v) == (v.interior_product(f)).exterior_derivative() + \
....:                        v.interior_product(f.exterior_derivative())
True

Computing the Hodge dual with respect to a given metric:

sage: h = U.metric('h')
sage: h[0,0] = 1+y^2
sage: h[1,1] = 1+z^2
sage: h[2,2] = 1+x^2
sage: h.display()
h = (y^2 + 1) dx*dx + (z^2 + 1) dy*dy + (x^2 + 1) dz*dz
sage: f.hodge_dual(h)
1-form *f on the 3-dimensional differentiable manifold U
sage: f.hodge_dual(h).display()
*f = sqrt(y^2 + 1)*y*z/(sqrt(x^2 + 1)*sqrt(z^2 + 1)) dx + sqrt(x^2 + 1)*x*sin(z)/(sqrt(y^2 + 1)*sqrt(z^2 + 1)) dz

Computing new components under a change of coordinates:

sage: X2.<u,v,w> = U.chart()
sage: X_to_X2 = X.transition_map(X2, [y+z, z+x, x+y])
sage: X_to_X2.inverse()
Change of coordinates from Chart (U, (u, v, w)) to Chart (U, (x, y, z))
sage: g.display()  # the default for g.display(X.frame(), X)
g = y^2 dx - z dy + (2*x - y) dz
sage: g.display(X2.frame(), X2)
g = (-1/8*u^2 + 1/4*(u + 2)*v - 1/8*v^2 - 1/4*(u - v - 2)*w - 1/8*w^2 - u) du + (1/8*u^2 - 1/4*(u - 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 - 1/2*u) dv + (1/8*u^2 - 1/4*(u + 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 + 1/2*u) dw

Using the function display_comp, which is more convenient for lengthy expressions:

sage: g.display_comp()   # the default for g.display_comp(X.frame(), X)
g_x = y^2 
g_y = -z 
g_z = 2*x - y 
sage: g.display_comp(X2.frame(), X2)
g_u = -1/8*u^2 + 1/4*(u + 2)*v - 1/8*v^2 - 1/4*(u - v - 2)*w - 1/8*w^2 - u 
g_v = 1/8*u^2 - 1/4*(u - 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 - 1/2*u 
g_w = 1/8*u^2 - 1/4*(u + 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 + 1/2*u