Pseudo-Riemannian Manifolds - Manifolds

Skip to content
Back to top
View this page
Edit this page

# Pseudo-Riemannian Manifolds

A pseudo-Riemannian manifold is a pair \((M,g)\) where \(M\) is a real differentiable manifold \(M\) (see `DifferentiableManifold`) and \(g\) is a field of non-degenerate symmetric bilinear forms on \(M\), which is called the metric tensor, or simply the metric (see `PseudoRiemannianMetric`).

Two important subcases are

- Riemannian manifold: the metric \(g\) is positive definite, i.e. its signature is \(n = \dim M\);

- Lorentzian manifold: the metric \(g\) has signature \(n-2\) (positive convention) or \(2-n\) (negative convention).

On a pseudo-Riemannian manifold, one may use various standard `operators` acting on scalar and tensor fields, like `grad()` or `div()`.

All pseudo-Riemannian manifolds, whatever the metric signature, are implemented via the class `PseudoRiemannianManifold`.

Example 1: the sphere as a Riemannian manifold of dimension 2

We start by declaring \(S^2\) as a 2-dimensional Riemannian manifold:

Sage

    sage: M = Manifold(2, 'S^2', structure='Riemannian')
    sage: M
    2-dimensional Riemannian manifold S^2

Python

    >>> from sage.all import *
    >>> M = Manifold(Integer(2), 'S^2', structure='Riemannian')
    >>> M
    2-dimensional Riemannian manifold S^2

We then cover \(S^2\) by two stereographic charts, from the North pole and from the South pole respectively:

Sage

    sage: U = M.open_subset('U')
    sage: stereoN.<x,y> = U.chart()
    sage: V = M.open_subset('V')
    sage: stereoS.<u,v> = V.chart()
    sage: M.declare_union(U,V)
    sage: stereoN_to_S = stereoN.transition_map(stereoS,
    ....:                [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: W = U.intersection(V)
    sage: stereoN_to_S
    Change of coordinates from Chart (W, (x, y)) to Chart (W, (u, v))
    sage: stereoN_to_S.display()
    u = x/(x^2 + y^2)
    v = y/(x^2 + y^2)
    sage: stereoN_to_S.inverse().display()
    x = u/(u^2 + v^2)
    y = v/(u^2 + v^2)

[Python]

    >>> from sage.all import *
    >>> U = M.open_subset('U')
    >>> stereoN = U.chart(names=('x', 'y',)); (x, y,) = stereoN._first_ngens(2)
    >>> V = M.open_subset('V')
    >>> stereoS = V.chart(names=('u', 'v',)); (u, v,) = stereoS._first_ngens(2)
    >>> M.declare_union(U,V)
    >>> stereoN_to_S = stereoN.transition_map(stereoS,
    ...                [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))
    >>> W = U.intersection(V)
    >>> stereoN_to_S
    Change of coordinates from Chart (W, (x, y)) to Chart (W, (u, v))
    >>> stereoN_to_S.display()
    u = x/(x^2 + y^2)
    v = y/(x^2 + y^2)
    >>> stereoN_to_S.inverse().display()
    x = u/(u^2 + v^2)
    y = v/(u^2 + v^2)

We get the metric defining the Riemannian structure by:

Sage

    sage: g = M.metric()
    sage: g
    Riemannian metric g on the 2-dimensional Riemannian manifold S^2

Python

    >>> from sage.all import *
    >>> g = M.metric()
    >>> g
    Riemannian metric g on the 2-dimensional Riemannian manifold S^2

At this stage, the metric \(g\) is defined as a Python object but there remains to initialize it by setting its components with respect to the vector frames associated with the stereographic coordinates. Let us begin with the frame of chart `stereoN`:

Sage

    sage: eU = stereoN.frame()
    sage: g[eU, 0, 0] = 4/(1 + x^2 + y^2)^2
    sage: g[eU, 1, 1] = 4/(1 + x^2 + y^2)^2

[Python]

    >>> from sage.all import *
    >>> eU = stereoN.frame()
    >>> g[eU, Integer(0), Integer(0)] = Integer(4)/(Integer(1) + x**Integer(2) + y**Integer(2))**Integer(2)
    >>> g[eU, Integer(1), Integer(1)] = Integer(4)/(Integer(1) + x**Integer(2) + y**Integer(2))**Integer(2)

The metric components in the frame of chart `stereoS` are obtained by continuation of the expressions found in \(W = U\cap V\) from the known change-of-coordinate formulas:

Sage

    sage: eV = stereoS.frame()
    sage: g.add_comp_by_continuation(eV, W)

Python

    >>> from sage.all import *
    >>> eV = stereoS.frame()
    >>> g.add_comp_by_continuation(eV, W)

At this stage, the metric \(g\) is well defined in all \(S^2\):

Sage

    sage: g.display(eU)
    g = 4/(x^2 + y^2 + 1)^2 dx⊗dx + 4/(x^2 + y^2 + 1)^2 dy⊗dy
    sage: g.display(eV)
    g = 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) du⊗du
     + 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) dv⊗dv

[Python]

    >>> from sage.all import *
    >>> g.display(eU)
    g = 4/(x^2 + y^2 + 1)^2 dx⊗dx + 4/(x^2 + y^2 + 1)^2 dy⊗dy
    >>> g.display(eV)
    g = 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) du⊗du
     + 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) dv⊗dv

The expression in frame `eV` can be given a shape similar to that in frame `eU`, by factorizing the components:

Sage

    sage: g[eV, 0, 0].factor()
    4/(u^2 + v^2 + 1)^2
    sage: g[eV, 1, 1].factor()
    4/(u^2 + v^2 + 1)^2
    sage: g.display(eV)
    g = 4/(u^2 + v^2 + 1)^2 du⊗du + 4/(u^2 + v^2 + 1)^2 dv⊗dv

Python

    >>> from sage.all import *
    >>> g[eV, Integer(0), Integer(0)].factor()
    4/(u^2 + v^2 + 1)^2
    >>> g[eV, Integer(1), Integer(1)].factor()
    4/(u^2 + v^2 + 1)^2
    >>> g.display(eV)
    g = 4/(u^2 + v^2 + 1)^2 du⊗du + 4/(u^2 + v^2 + 1)^2 dv⊗dv

Let us consider a scalar field \(f\) on \(S^2\):

Sage

    sage: f = M.scalar_field({stereoN: 1/(1+x^2+y^2)}, name='f')
    sage: f.add_expr_by_continuation(stereoS, W)
    sage: f.display()
    f: S^2 → ℝ
    on U: (x, y) ↦ 1/(x^2 + y^2 + 1)
    on V: (u, v) ↦ (u^2 + v^2)/(u^2 + v^2 + 1)

[Python]

    >>> from sage.all import *
    >>> f = M.scalar_field({stereoN: Integer(1)/(Integer(1)+x**Integer(2)+y**Integer(2))}, name='f')
    >>> f.add_expr_by_continuation(stereoS, W)
    >>> f.display()
    f: S^2 → ℝ
    on U: (x, y) ↦ 1/(x^2 + y^2 + 1)
    on V: (u, v) ↦ (u^2 + v^2)/(u^2 + v^2 + 1)

The gradient of \(f\) (with respect to the metric \(g\)) is:

Sage

    sage: gradf = f.gradient()
    sage: gradf
    Vector field grad(f) on the 2-dimensional Riemannian manifold S^2
    sage: gradf.display(eU)
    grad(f) = -1/2*x ∂/∂x - 1/2*y ∂/∂y
    sage: gradf.display(eV)
    grad(f) = 1/2*u ∂/∂u + 1/2*v ∂/∂v

Python

    >>> from sage.all import *
    >>> gradf = f.gradient()
    >>> gradf
    Vector field grad(f) on the 2-dimensional Riemannian manifold S^2
    >>> gradf.display(eU)
    grad(f) = -1/2*x ∂/∂x - 1/2*y ∂/∂y
    >>> gradf.display(eV)
    grad(f) = 1/2*u ∂/∂u + 1/2*v ∂/∂v

It is possible to write `grad(f)` instead of `f.gradient()`, by importing the standard differential operators of vector calculus:

Sage

    sage: from sage.manifolds.operators import *
    sage: grad(f) == gradf
    True

[Python]

    >>> from sage.all import *
    >>> from sage.manifolds.operators import *
    >>> grad(f) == gradf
    True

The Laplacian of \(f\) (with respect to the metric \(g\)) is obtained either as `f.laplacian()` or, thanks to the above import, as `laplacian(f)`:

Sage

    sage: Df = laplacian(f)
    sage: Df
    Scalar field Delta(f) on the 2-dimensional Riemannian manifold S^2
    sage: Df.display()
    Delta(f): S^2 → ℝ
    on U: (x, y) ↦ (x^2 + y^2 - 1)/(x^2 + y^2 + 1)
    on V: (u, v) ↦ -(u^2 + v^2 - 1)/(u^2 + v^2 + 1)

Python

    >>> from sage.all import *
    >>> Df = laplacian(f)
    >>> Df
    Scalar field Delta(f) on the 2-dimensional Riemannian manifold S^2
    >>> Df.display()
    Delta(f): S^2 → ℝ
    on U: (x, y) ↦ (x^2 + y^2 - 1)/(x^2 + y^2 + 1)
    on V: (u, v) ↦ -(u^2 + v^2 - 1)/(u^2 + v^2 + 1)

Let us check the standard formula \(\Delta f = \mathrm{div}( \mathrm{grad}\, f )\):

Sage

    sage: Df == div(gradf)
    True

[Python]

    >>> from sage.all import *
    >>> Df == div(gradf)
    True

Since each open subset of \(S^2\) inherits the structure of a Riemannian manifold, we can get the metric on it via the method `metric()`:

Sage

    sage: gU = U.metric()
    sage: gU
    Riemannian metric g on the Open subset U of the 2-dimensional Riemannian
     manifold S^2
    sage: gU.display()
    g = 4/(x^2 + y^2 + 1)^2 dx⊗dx + 4/(x^2 + y^2 + 1)^2 dy⊗dy

Python

    >>> from sage.all import *
    >>> gU = U.metric()
    >>> gU
    Riemannian metric g on the Open subset U of the 2-dimensional Riemannian
     manifold S^2
    >>> gU.display()
    g = 4/(x^2 + y^2 + 1)^2 dx⊗dx + 4/(x^2 + y^2 + 1)^2 dy⊗dy

Of course, `gU` is nothing but the restriction of \(g\) to \(U\):

Sage

    sage: gU is g.restrict(U)
    True

[Python]

    >>> from sage.all import *
    >>> gU is g.restrict(U)
    True

Example 2: Minkowski spacetime as a Lorentzian manifold of dimension 4

We start by declaring a 4-dimensional Lorentzian manifold \(M\):

Sage

    sage: M = Manifold(4, 'M', structure='Lorentzian')
    sage: M
    4-dimensional Lorentzian manifold M

Python

    >>> from sage.all import *
    >>> M = Manifold(Integer(4), 'M', structure='Lorentzian')
    >>> M
    4-dimensional Lorentzian manifold M

We define Minkowskian coordinates on \(M\):

Sage

    sage: X.<t,x,y,z> = M.chart()

[Python]

    >>> from sage.all import *
    >>> X = M.chart(names=('t', 'x', 'y', 'z',)); (t, x, y, z,) = X._first_ngens(4)

We construct the metric tensor by:

Sage

    sage: g = M.metric()
    sage: g
    Lorentzian metric g on the 4-dimensional Lorentzian manifold M

Python

    >>> from sage.all import *
    >>> g = M.metric()
    >>> g
    Lorentzian metric g on the 4-dimensional Lorentzian manifold M

and initialize it to the Minkowskian value:

Sage

    sage: g[0,0], g[1,1], g[2,2], g[3,3] = -1, 1, 1, 1
    sage: g.display()
    g = -dt⊗dt + dx⊗dx + dy⊗dy + dz⊗dz
    sage: g[:]
    [-1  0  0  0]
    [ 0  1  0  0]
    [ 0  0  1  0]
    [ 0  0  0  1]

[Python]

    >>> from sage.all import *
    >>> g[Integer(0),Integer(0)], g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = -Integer(1), Integer(1), Integer(1), Integer(1)
    >>> g.display()
    g = -dt⊗dt + dx⊗dx + dy⊗dy + dz⊗dz
    >>> g[:]
    [-1  0  0  0]
    [ 0  1  0  0]
    [ 0  0  1  0]
    [ 0  0  0  1]

We may check that the metric is flat, i.e. has a vanishing Riemann curvature tensor:

Sage

    sage: g.riemann().display()
    Riem(g) = 0

Python

    >>> from sage.all import *
    >>> g.riemann().display()
    Riem(g) = 0

A vector field on \(M\):

Sage

    sage: u = M.vector_field(name='u')
    sage: u[0] = cosh(t)
    sage: u[1] = sinh(t)
    sage: u.display()
    u = cosh(t) ∂/∂t + sinh(t) ∂/∂x

[Python]

    >>> from sage.all import *
    >>> u = M.vector_field(name='u')
    >>> u[Integer(0)] = cosh(t)
    >>> u[Integer(1)] = sinh(t)
    >>> u.display()
    u = cosh(t) ∂/∂t + sinh(t) ∂/∂x

The scalar square of \(u\) is:

Sage

    sage: s = u.dot(u); s
    Scalar field u.u on the 4-dimensional Lorentzian manifold M

Python

    >>> from sage.all import *
    >>> s = u.dot(u); s
    Scalar field u.u on the 4-dimensional Lorentzian manifold M

Scalar products are taken with respect to the metric tensor:

Sage

    sage: u.dot(u) == g(u,u)
    True

[Python]

    >>> from sage.all import *
    >>> u.dot(u) == g(u,u)
    True

\(u\) is a unit timelike vector, i.e. its scalar square is identically \(-1\):

Sage

    sage: s.display()
    u.u: M → ℝ
       (t, x, y, z) ↦ -1
    sage: s.expr()
    -1

Python

    >>> from sage.all import *
    >>> s.display()
    u.u: M → ℝ
       (t, x, y, z) ↦ -1
    >>> s.expr()
    -1

Let us consider a unit spacelike vector:

Sage

    sage: v = M.vector_field(name='v')
    sage: v[0] = sinh(t)
    sage: v[1] = cosh(t)
    sage: v.display()
    v = sinh(t) ∂/∂t + cosh(t) ∂/∂x
    sage: v.dot(v).display()
    v.v: M → ℝ
       (t, x, y, z) ↦ 1
    sage: v.dot(v).expr()
    1

[Python]

    >>> from sage.all import *
    >>> v = M.vector_field(name='v')
    >>> v[Integer(0)] = sinh(t)
    >>> v[Integer(1)] = cosh(t)
    >>> v.display()
    v = sinh(t) ∂/∂t + cosh(t) ∂/∂x
    >>> v.dot(v).display()
    v.v: M → ℝ
       (t, x, y, z) ↦ 1
    >>> v.dot(v).expr()
    1

\(u\) and \(v\) are orthogonal vectors with respect to Minkowski metric:

Sage

    sage: u.dot(v).display()
        u.v: M → ℝ
       (t, x, y, z) ↦ 0
    sage: u.dot(v).expr()
    0

Python

    >>> from sage.all import *
    >>> u.dot(v).display()
        u.v: M → ℝ
       (t, x, y, z) ↦ 0
    >>> u.dot(v).expr()
    0

The divergence of \(u\) is:

Sage

    sage: s = u.div(); s
    Scalar field div(u) on the 4-dimensional Lorentzian manifold M
    sage: s.display()
    div(u): M → ℝ
       (t, x, y, z) ↦ sinh(t)

[Python]

    >>> from sage.all import *
    >>> s = u.div(); s
    Scalar field div(u) on the 4-dimensional Lorentzian manifold M
    >>> s.display()
    div(u): M → ℝ
       (t, x, y, z) ↦ sinh(t)

while its d’Alembertian is:

Sage

    sage: Du = u.dalembertian(); Du
    Vector field Box(u) on the 4-dimensional Lorentzian manifold M
    sage: Du.display()
    Box(u) = -cosh(t) ∂/∂t - sinh(t) ∂/∂x

Python

    >>> from sage.all import *
    >>> Du = u.dalembertian(); Du
    Vector field Box(u) on the 4-dimensional Lorentzian manifold M
    >>> Du.display()
    Box(u) = -cosh(t) ∂/∂t - sinh(t) ∂/∂x

AUTHORS:

- Eric Gourgoulhon (2018): initial version

REFERENCES:

- B. O’Neill : Semi-Riemannian Geometry [ONe1983]

- J. M. Lee : Riemannian Manifolds [Lee1997]

class sage.manifolds.differentiable.pseudo_riemannian.PseudoRiemannianManifold(n, name, metric_name=None, signature=None, base_manifold=None, diff_degree=+Infinity, latex_name=None, metric_latex_name=None, start_index=0, category=None, unique_tag=None)

  Bases: `DifferentiableManifold`

  PseudoRiemannian manifold.

  A pseudo-Riemannian manifold is a pair \((M,g)\) where \(M\) is a real differentiable manifold \(M\) (see `DifferentiableManifold`) and \(g\) is a field of non-degenerate symmetric bilinear forms on \(M\), which is called the metric tensor, or simply the metric (see `PseudoRiemannianMetric`).

  Two important subcases are

  - Riemannian manifold: the metric \(g\) is positive definite, i.e. its signature is \(n = \dim M\);

  - Lorentzian manifold: the metric \(g\) has signature \(n-2\) (positive convention) or \(2-n\) (negative convention).

  INPUT:

  - `n` – positive integer; dimension of the manifold

  - `name` – string; name (symbol) given to the manifold

  - `metric_name` – (default: `None`) string; name (symbol) given to the metric; if `None`, `'g'` is used

  - `signature` – (default: `None`) signature \(S\) of the metric as a single integer: \(S = n_+ - n_-\), where \(n_+\) (resp. \(n_-\)) is the number of positive terms (resp. number of negative terms) in any diagonal writing of the metric components; if `signature` is not provided, \(S\) is set to the manifold’s dimension (Riemannian signature)

  - `base_manifold` – (default: `None`) if not `None`, must be a differentiable manifold; the created object is then an open subset of `base_manifold`

  - `diff_degree` – (default: `infinity`) degree \(k\) of differentiability

  - `latex_name` – (default: `None`) string; LaTeX symbol to denote the manifold; if none is provided, it is set to `name`

  - `metric_latex_name` – (default: `None`) string; LaTeX symbol to denote the metric; if none is provided, it is set to `metric_name`

  - `start_index` – (default: 0) integer; lower value of the range of indices used for “indexed objects” on the manifold, e.g. coordinates in a chart

  - `category` – (default: `None`) to specify the category; if `None`, `Manifolds(RR).Differentiable()` (or `Manifolds(RR).Smooth()` if `diff_degree` = `infinity`) is assumed (see the category `Manifolds`)

  - `unique_tag` – (default: `None`) tag used to force the construction of a new object when all the other arguments have been used previously (without `unique_tag`, the `UniqueRepresentation` behavior inherited from `ManifoldSubset`, via `DifferentiableManifold` and `TopologicalManifold`, would return the previously constructed object corresponding to these arguments).

  EXAMPLES:

  Pseudo-Riemannian manifolds are constructed via the generic function `Manifold()`, using the keyword `structure`:

  Sage

      sage: M = Manifold(4, 'M', structure='pseudo-Riemannian', signature=0)
      sage: M
      4-dimensional pseudo-Riemannian manifold M
      sage: M.category()
      Category of smooth manifolds over Real Field with 53 bits of precision

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(4), 'M', structure='pseudo-Riemannian', signature=Integer(0))
      >>> M
      4-dimensional pseudo-Riemannian manifold M
      >>> M.category()
      Category of smooth manifolds over Real Field with 53 bits of precision

  The metric associated with `M` is:

  Sage

      sage: M.metric()
      Pseudo-Riemannian metric g on the 4-dimensional pseudo-Riemannian
       manifold M
      sage: M.metric().signature()
      0
      sage: M.metric().tensor_type()
      (0, 2)

  [Python]

      >>> from sage.all import *
      >>> M.metric()
      Pseudo-Riemannian metric g on the 4-dimensional pseudo-Riemannian
       manifold M
      >>> M.metric().signature()
      0
      >>> M.metric().tensor_type()
      (0, 2)

  Its value has to be initialized either by setting its components in various vector frames (see the above examples regarding the 2-sphere and Minkowski spacetime) or by making it equal to a given field of symmetric bilinear forms (see the method `set()` of the metric class). Both methods are also covered in the documentation of method `metric()` below.

  The metric object belongs to the class `PseudoRiemannianMetric`:

  Sage

      sage: isinstance(M.metric(), sage.manifolds.differentiable.metric.
      ....:                        PseudoRiemannianMetric)
      True

  Python

      >>> from sage.all import *
      >>> isinstance(M.metric(), sage.manifolds.differentiable.metric.
      ...                        PseudoRiemannianMetric)
      True

  See the documentation of this class for all operations available on metrics.

  The default name of the metric is `g`; it can be customized:

  Sage

      sage: M = Manifold(4, 'M', structure='pseudo-Riemannian',
      ....:              metric_name='gam', metric_latex_name=r'\gamma')
      sage: M.metric()
      Riemannian metric gam on the 4-dimensional Riemannian manifold M
      sage: latex(M.metric())
      \gamma

  [Python]

      >>> from sage.all import *
      >>> M = Manifold(Integer(4), 'M', structure='pseudo-Riemannian',
      ...              metric_name='gam', metric_latex_name=r'\gamma')
      >>> M.metric()
      Riemannian metric gam on the 4-dimensional Riemannian manifold M
      >>> latex(M.metric())
      \gamma

  A Riemannian manifold is constructed by the proper setting of the keyword `structure`:

  Sage

      sage: M = Manifold(4, 'M', structure='Riemannian'); M
      4-dimensional Riemannian manifold M
      sage: M.metric()
      Riemannian metric g on the 4-dimensional Riemannian manifold M
      sage: M.metric().signature()
      4

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(4), 'M', structure='Riemannian'); M
      4-dimensional Riemannian manifold M
      >>> M.metric()
      Riemannian metric g on the 4-dimensional Riemannian manifold M
      >>> M.metric().signature()
      4

  Similarly, a Lorentzian manifold is obtained by:

  Sage

      sage: M = Manifold(4, 'M', structure='Lorentzian'); M
      4-dimensional Lorentzian manifold M
      sage: M.metric()
      Lorentzian metric g on the 4-dimensional Lorentzian manifold M

  [Python]

      >>> from sage.all import *
      >>> M = Manifold(Integer(4), 'M', structure='Lorentzian'); M
      4-dimensional Lorentzian manifold M
      >>> M.metric()
      Lorentzian metric g on the 4-dimensional Lorentzian manifold M

  The default Lorentzian signature is taken to be positive:

  Sage

      sage: M.metric().signature()
      2

  Python

      >>> from sage.all import *
      >>> M.metric().signature()
      2

  but one can opt for the negative convention via the keyword `signature`:

  Sage

      sage: M = Manifold(4, 'M', structure='Lorentzian', signature='negative')
      sage: M.metric()
      Lorentzian metric g on the 4-dimensional Lorentzian manifold M
      sage: M.metric().signature()
      -2

  [Python]

      >>> from sage.all import *
      >>> M = Manifold(Integer(4), 'M', structure='Lorentzian', signature='negative')
      >>> M.metric()
      Lorentzian metric g on the 4-dimensional Lorentzian manifold M
      >>> M.metric().signature()
      -2

  metric(name=None, signature=None, latex_name=None, dest_map=None)

    Return the metric giving the pseudo-Riemannian structure to the manifold, or define a new metric tensor on the manifold.

    INPUT:

    - `name` – (default: `None`) name given to the metric; if `name` is `None` or matches the name of the metric defining the pseudo-Riemannian structure of `self`, the latter metric is returned

    - `signature` – (default: `None`; ignored if `name` is `None`) signature \(S\) of the metric as a single integer: \(S = n_+ - n_-\), where \(n_+\) (resp. \(n_-\)) is the number of positive terms (resp. number of negative terms) in any diagonal writing of the metric components; if `signature` is not provided, \(S\) is set to the manifold’s dimension (Riemannian signature)

    - `latex_name` – (default: `None`; ignored if `name` is `None`) LaTeX symbol to denote the metric; if `None`, it is formed from `name`

    - `dest_map` – (default: `None`; ignored if `name` is `None`) instance of class `DiffMap` representing the destination map \(\Phi:\ U \rightarrow M\), where \(U\) is the current manifold; if `None`, the identity map is assumed (case of a metric tensor field on \(U\))

    OUTPUT:

    - instance of `PseudoRiemannianMetric`

    EXAMPLES:

    Metric of a 3-dimensional Riemannian manifold:

    Sage

        sage: M = Manifold(3, 'M', structure='Riemannian', start_index=1)
        sage: X.<x,y,z> = M.chart()
        sage: g = M.metric(); g
        Riemannian metric g on the 3-dimensional Riemannian manifold M

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'M', structure='Riemannian', start_index=Integer(1))
        >>> X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3)
        >>> g = M.metric(); g
        Riemannian metric g on the 3-dimensional Riemannian manifold M

    The metric remains to be initialized, for instance by setting its components in the coordinate frame associated to the chart `X`:

    Sage

        sage: g[1,1], g[2,2], g[3,3] = 1, 1, 1
        sage: g.display()
        g = dx⊗dx + dy⊗dy + dz⊗dz

    [Python]

        >>> from sage.all import *
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = Integer(1), Integer(1), Integer(1)
        >>> g.display()
        g = dx⊗dx + dy⊗dy + dz⊗dz

    Alternatively, the metric can be initialized from a given field of nondegenerate symmetric bilinear forms; we may create the former object by:

    Sage

        sage: X.coframe()
        Coordinate coframe (M, (dx,dy,dz))
        sage: dx, dy, dz = X.coframe()[1], X.coframe()[2], X.coframe()[3]
        sage: b = dx*dx + dy*dy + dz*dz
        sage: b
        Field of symmetric bilinear forms dx⊗dx+dy⊗dy+dz⊗dz on the
         3-dimensional Riemannian manifold M

    Python

        >>> from sage.all import *
        >>> X.coframe()
        Coordinate coframe (M, (dx,dy,dz))
        >>> dx, dy, dz = X.coframe()[Integer(1)], X.coframe()[Integer(2)], X.coframe()[Integer(3)]
        >>> b = dx*dx + dy*dy + dz*dz
        >>> b
        Field of symmetric bilinear forms dx⊗dx+dy⊗dy+dz⊗dz on the
         3-dimensional Riemannian manifold M

    We then use the metric method `set()` to make `g` being equal to `b` as a symmetric tensor field of type `(0,2)`:

    Sage

        sage: g.set(b)
        sage: g.display()
        g = dx⊗dx + dy⊗dy + dz⊗dz

    [Python]

        >>> from sage.all import *
        >>> g.set(b)
        >>> g.display()
        g = dx⊗dx + dy⊗dy + dz⊗dz

    Another metric can be defined on `M` by specifying a metric name distinct from that chosen at the creation of the manifold (which is `g` by default, but can be changed thanks to the keyword `metric_name` in `Manifold()`):

    Sage

        sage: h = M.metric('h'); h
        Riemannian metric h on the 3-dimensional Riemannian manifold M
        sage: h[1,1], h[2,2], h[3,3] = 1+y^2, 1+z^2, 1+x^2
        sage: h.display()
        h = (y^2 + 1) dx⊗dx + (z^2 + 1) dy⊗dy + (x^2 + 1) dz⊗dz

    Python

        >>> from sage.all import *
        >>> h = M.metric('h'); h
        Riemannian metric h on the 3-dimensional Riemannian manifold M
        >>> h[Integer(1),Integer(1)], h[Integer(2),Integer(2)], h[Integer(3),Integer(3)] = Integer(1)+y**Integer(2), Integer(1)+z**Integer(2), Integer(1)+x**Integer(2)
        >>> h.display()
        h = (y^2 + 1) dx⊗dx + (z^2 + 1) dy⊗dy + (x^2 + 1) dz⊗dz

    The metric tensor `h` is distinct from the metric entering in the definition of the Riemannian manifold `M`:

    Sage

        sage: h is M.metric()
        False

    [Python]

        >>> from sage.all import *
        >>> h is M.metric()
        False

    while we have of course:

    Sage

        sage: g is M.metric()
        True

    Python

        >>> from sage.all import *
        >>> g is M.metric()
        True

    Providing the same name as the manifold’s default metric returns the latter:

    Sage

        sage: M.metric('g') is M.metric()
        True

    [Python]

        >>> from sage.all import *
        >>> M.metric('g') is M.metric()
        True

    In the present case (`M` is diffeomorphic to \(\RR^3\)), we can even create a Lorentzian metric on `M`:

    Sage

        sage: h = M.metric('h', signature=1); h
        Lorentzian metric h on the 3-dimensional Riemannian manifold M

    Python

        >>> from sage.all import *
        >>> h = M.metric('h', signature=Integer(1)); h
        Lorentzian metric h on the 3-dimensional Riemannian manifold M

  open_subset(name, latex_name=None, coord_def={}, supersets=None)

    Create an open subset of `self`.

    An open subset is a set that is (i) included in the manifold and (ii) open with respect to the manifold’s topology. It is a differentiable manifold by itself. Moreover, equipped with the restriction of the manifold metric to itself, it is a pseudo-Riemannian manifold. Hence the returned object is an instance of `PseudoRiemannianManifold`.

    INPUT:

    - `name` – name given to the open subset

    - `latex_name` – (default: `None`) LaTeX symbol to denote the subset; if none is provided, it is set to `name`

    - `coord_def` – (default: {}) definition of the subset in terms of coordinates; `coord_def` must a be dictionary with keys charts in the manifold’s atlas and values the symbolic expressions formed by the coordinates to define the subset.

    - `supersets` – (default: only `self`) list of sets that the new open subset is a subset of

    OUTPUT:

    - instance of `PseudoRiemannianManifold` representing the created open subset

    EXAMPLES:

    Open subset of a 2-dimensional Riemannian manifold:

    Sage

        sage: M = Manifold(2, 'M', structure='Riemannian')
        sage: X.<x,y> = M.chart()
        sage: U = M.open_subset('U', coord_def={X: x>0}); U
        Open subset U of the 2-dimensional Riemannian manifold M
        sage: type(U)
        <class 'sage.manifolds.differentiable.pseudo_riemannian.PseudoRiemannianManifold_with_category'>

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M', structure='Riemannian')
        >>> X = M.chart(names=('x', 'y',)); (x, y,) = X._first_ngens(2)
        >>> U = M.open_subset('U', coord_def={X: x>Integer(0)}); U
        Open subset U of the 2-dimensional Riemannian manifold M
        >>> type(U)
        <class 'sage.manifolds.differentiable.pseudo_riemannian.PseudoRiemannianManifold_with_category'>

    We initialize the metric of `M`:

    Sage

        sage: g = M.metric()
        sage: g[0,0], g[1,1] = 1, 1

    [Python]

        >>> from sage.all import *
        >>> g = M.metric()
        >>> g[Integer(0),Integer(0)], g[Integer(1),Integer(1)] = Integer(1), Integer(1)

    Then the metric on `U` is determined as the restriction of `g` to `U`:

    Sage

        sage: gU = U.metric(); gU
        Riemannian metric g on the Open subset U of the 2-dimensional Riemannian manifold M
        sage: gU.display()
        g = dx⊗dx + dy⊗dy
        sage: gU is g.restrict(U)
        True

    Python

        >>> from sage.all import *
        >>> gU = U.metric(); gU
        Riemannian metric g on the Open subset U of the 2-dimensional Riemannian manifold M
        >>> gU.display()
        g = dx⊗dx + dy⊗dy
        >>> gU is g.restrict(U)
        True

  volume_form(contra=0)

    Volume form (Levi-Civita tensor) \(\epsilon\) associated with `self`.

    This assumes that `self` is an orientable manifold, with a preferred orientation; see `orientation()` for details.

    The volume form \(\epsilon\) is a \(n\)-form (\(n\) being the manifold’s dimension) such that, for any vector frame \((e_i)\) that is orthonormal with respect to the metric of the pseudo-Riemannian manifold `self`,

    \[\epsilon(e_1,\ldots,e_n) = \pm 1\]

    There are only two such \(n\)-forms, which are opposite of each other. The volume form \(\epsilon\) is selected as the one that returns \(+1\) for any right-handed vector frame with respect to the chosen orientation of `self`.

    INPUT:

    - `contra` – (default: 0) number of contravariant indices of the returned tensor

    OUTPUT:

    - if `contra = 0` (default value): the volume \(n\)-form \(\epsilon\), as an instance of `DiffForm`

    - if `contra = k`, with \(1\leq k \leq n\), the tensor field of type (k,n-k) formed from \(\epsilon\) by raising the first k indices with the metric (see method `up()`); the output is then an instance of `TensorField`, with the appropriate antisymmetries, or of the subclass `MultivectorField` if \(k=n\)

    EXAMPLES:

    Volume form of the Euclidean 3-space:

    Sage

        sage: M = Manifold(3, 'M', structure='Riemannian', start_index=1)
        sage: X.<x,y,z> = M.chart()
        sage: g = M.metric()
        sage: g[1,1], g[2,2], g[3,3] = 1, 1, 1
        sage: eps = M.volume_form(); eps
        3-form eps_g on the 3-dimensional Riemannian manifold M
        sage: eps.display()
        eps_g = dx∧dy∧dz

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'M', structure='Riemannian', start_index=Integer(1))
        >>> X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3)
        >>> g = M.metric()
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = Integer(1), Integer(1), Integer(1)
        >>> eps = M.volume_form(); eps
        3-form eps_g on the 3-dimensional Riemannian manifold M
        >>> eps.display()
        eps_g = dx∧dy∧dz

    Raising the first index:

    Sage

        sage: eps1 = M.volume_form(1); eps1
        Tensor field of type (1,2) on the 3-dimensional Riemannian
         manifold M
        sage: eps1.display()
        ∂/∂x⊗dy⊗dz - ∂/∂x⊗dz⊗dy - ∂/∂y⊗dx⊗dz + ∂/∂y⊗dz⊗dx + ∂/∂z⊗dx⊗dy
         - ∂/∂z⊗dy⊗dx
        sage: eps1.symmetries()
        no symmetry; antisymmetry: (1, 2)

    [Python]

        >>> from sage.all import *
        >>> eps1 = M.volume_form(Integer(1)); eps1
        Tensor field of type (1,2) on the 3-dimensional Riemannian
         manifold M
        >>> eps1.display()
        ∂/∂x⊗dy⊗dz - ∂/∂x⊗dz⊗dy - ∂/∂y⊗dx⊗dz + ∂/∂y⊗dz⊗dx + ∂/∂z⊗dx⊗dy
         - ∂/∂z⊗dy⊗dx
        >>> eps1.symmetries()
        no symmetry; antisymmetry: (1, 2)

    Raising the first and second indices:

    Sage

        sage: eps2 = M.volume_form(2); eps2
        Tensor field of type (2,1) on the 3-dimensional Riemannian
         manifold M
        sage: eps2.display()
        ∂/∂x⊗∂/∂y⊗dz - ∂/∂x⊗∂/∂z⊗dy - ∂/∂y⊗∂/∂x⊗dz + ∂/∂y⊗∂/∂z⊗dx
         + ∂/∂z⊗∂/∂x⊗dy - ∂/∂z⊗∂/∂y⊗dx
        sage: eps2.symmetries()
        no symmetry; antisymmetry: (0, 1)

    Python

        >>> from sage.all import *
        >>> eps2 = M.volume_form(Integer(2)); eps2
        Tensor field of type (2,1) on the 3-dimensional Riemannian
         manifold M
        >>> eps2.display()
        ∂/∂x⊗∂/∂y⊗dz - ∂/∂x⊗∂/∂z⊗dy - ∂/∂y⊗∂/∂x⊗dz + ∂/∂y⊗∂/∂z⊗dx
         + ∂/∂z⊗∂/∂x⊗dy - ∂/∂z⊗∂/∂y⊗dx
        >>> eps2.symmetries()
        no symmetry; antisymmetry: (0, 1)

    Fully contravariant version:

    Sage

        sage: eps3 = M.volume_form(3); eps3
        3-vector field on the 3-dimensional Riemannian manifold M
        sage: eps3.display()
        ∂/∂x∧∂/∂y∧∂/∂z

    [Python]

        >>> from sage.all import *
        >>> eps3 = M.volume_form(Integer(3)); eps3
        3-vector field on the 3-dimensional Riemannian manifold M
        >>> eps3.display()
        ∂/∂x∧∂/∂y∧∂/∂z