Vector Fields - Manifolds

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

# Vector Fields

Given two differentiable manifolds \(U\) and \(M\) over the same topological field \(K\) and a differentiable map

\[\Phi:\ U \longrightarrow M,\]

we define a vector field along \(U\) with values on \(M\) to be a differentiable map

\[v:\ U \longrightarrow TM\]

(\(TM\) being the tangent bundle of \(M\)) such that

\[\forall p \in U,\ v(p) \in T_{\Phi(p)}M.\]

The standard case of vector fields 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\)).

Vector fields are implemented via two classes: `VectorFieldParal` and `VectorField`, depending respectively whether the manifold \(M\) is parallelizable or not, i.e. whether the bundle \(TM\) is trivial or not.

AUTHORS:

- Eric Gourgoulhon, Michal Bejger (2013-2015) : initial version

- Marco Mancini (2015): parallelization of vector field plots

- Travis Scrimshaw (2016): review tweaks

- Eric Gourgoulhon (2017): vector fields inherit from multivector fields

- Eric Gourgoulhon (2018): dot and cross products, operators norm and curl

REFERENCES:

- [KN1963]

- [Lee2013]

- [ONe1983]

- [BG1988]

class sage.manifolds.differentiable.vectorfield.VectorField(vector_field_module, name=None, latex_name=None)

  Bases: `MultivectorField`

  Vector field along a differentiable manifold.

  An instance of this class is a vector field along a differentiable manifold \(U\) with values on a differentiable manifold \(M\), via a differentiable map \(U \rightarrow M\). More precisely, given a differentiable map

  \[\Phi:\ U \longrightarrow M,\]

  a vector field along \(U\) with values on \(M\) is a differentiable map

  \[v:\ U \longrightarrow TM\]

  (\(TM\) being the tangent bundle of \(M\)) such that

  \[\forall p \in U,\ v(p) \in T_{\Phi(p)}M.\]

  The standard case of vector fields 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\)).

  Note

  If \(M\) is parallelizable, then `VectorFieldParal` must be used instead.

  INPUT:

  - `vector_field_module` – module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(M\supset\Phi(U)\)

  - `name` – (default: `None`) name given to the vector field

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

  EXAMPLES:

  A vector field on a non-parallelizable 2-dimensional manifold:

  Sage

      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_tu.<t,u> = V.chart()
      sage: transf = c_xy.transition_map(c_tu, (x+y, x-y), intersection_name='W',
      ....:                              restrictions1= x>0, restrictions2= t+u>0)
      sage: inv = transf.inverse()
      sage: W = U.intersection(V)
      sage: eU = c_xy.frame() ; eV = c_tu.frame()
      sage: c_tuW = c_tu.restrict(W) ; eVW = c_tuW.frame()
      sage: v = M.vector_field(name='v') ; v
      Vector field v on the 2-dimensional differentiable manifold M
      sage: v.parent()
      Module X(M) of vector fields on the 2-dimensional differentiable
       manifold M

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(2), 'M')
      >>> U = M.open_subset('U') ; V = M.open_subset('V')
      >>> M.declare_union(U,V)   # M is the union of U and V
      >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2); c_tu = V.chart(names=('t', 'u',)); (t, u,) = c_tu._first_ngens(2)
      >>> transf = c_xy.transition_map(c_tu, (x+y, x-y), intersection_name='W',
      ...                              restrictions1= x>Integer(0), restrictions2= t+u>Integer(0))
      >>> inv = transf.inverse()
      >>> W = U.intersection(V)
      >>> eU = c_xy.frame() ; eV = c_tu.frame()
      >>> c_tuW = c_tu.restrict(W) ; eVW = c_tuW.frame()
      >>> v = M.vector_field(name='v') ; v
      Vector field v on the 2-dimensional differentiable manifold M
      >>> v.parent()
      Module X(M) of vector fields on the 2-dimensional differentiable
       manifold M

  The vector field is first defined on the domain \(U\) by means of its components with respect to the frame `eU`:

  Sage

      sage: v[eU,:] = [-y, 1+x]

  [Python]

      >>> from sage.all import *
      >>> v[eU,:] = [-y, Integer(1)+x]

  The components with respect to the frame `eV` are then deduced by continuation of the components with respect to the frame `eVW` on the domain \(W = U \cap V\), expressed in terms on the coordinates covering \(V\):

  Sage

      sage: v[eV,0] = v[eVW,0,c_tuW].expr()
      sage: v[eV,1] = v[eVW,1,c_tuW].expr()

  Python

      >>> from sage.all import *
      >>> v[eV,Integer(0)] = v[eVW,Integer(0),c_tuW].expr()
      >>> v[eV,Integer(1)] = v[eVW,Integer(1),c_tuW].expr()

  At this stage, the vector field is fully defined on the whole manifold:

  Sage

      sage: v.display(eU)
      v = -y ∂/∂x + (x + 1) ∂/∂y
      sage: v.display(eV)
      v = (u + 1) ∂/∂t + (-t - 1) ∂/∂u

  [Python]

      >>> from sage.all import *
      >>> v.display(eU)
      v = -y ∂/∂x + (x + 1) ∂/∂y
      >>> v.display(eV)
      v = (u + 1) ∂/∂t + (-t - 1) ∂/∂u

  The vector field acting on scalar fields:

  Sage

      sage: f = M.scalar_field({c_xy: (x+y)^2, c_tu: t^2}, name='f')
      sage: s = v(f) ; s
      Scalar field v(f) on the 2-dimensional differentiable manifold M
      sage: s.display()
      v(f): M → ℝ
      on U: (x, y) ↦ 2*x^2 - 2*y^2 + 2*x + 2*y
      on V: (t, u) ↦ 2*t*u + 2*t

  Python

      >>> from sage.all import *
      >>> f = M.scalar_field({c_xy: (x+y)**Integer(2), c_tu: t**Integer(2)}, name='f')
      >>> s = v(f) ; s
      Scalar field v(f) on the 2-dimensional differentiable manifold M
      >>> s.display()
      v(f): M → ℝ
      on U: (x, y) ↦ 2*x^2 - 2*y^2 + 2*x + 2*y
      on V: (t, u) ↦ 2*t*u + 2*t

  Some checks:

  Sage

      sage: v(f) == f.differential()(v)
      True
      sage: v(f) == f.lie_der(v)
      True

  [Python]

      >>> from sage.all import *
      >>> v(f) == f.differential()(v)
      True
      >>> v(f) == f.lie_der(v)
      True

  The result is defined on the intersection of the vector field’s domain and the scalar field’s one:

  Sage

      sage: s = v(f.restrict(U)) ; s
      Scalar field v(f) on the Open subset U of the 2-dimensional
       differentiable manifold M
      sage: s == v(f).restrict(U)
      True
      sage: s = v(f.restrict(W)) ; s
      Scalar field v(f) on the Open subset W of the 2-dimensional
       differentiable manifold M
      sage: s.display()
      v(f): W → ℝ
         (x, y) ↦ 2*x^2 - 2*y^2 + 2*x + 2*y
         (t, u) ↦ 2*t*u + 2*t
      sage: s = v.restrict(U)(f) ; s
      Scalar field v(f) on the Open subset U of the 2-dimensional
       differentiable manifold M
      sage: s.display()
      v(f): U → ℝ
         (x, y) ↦ 2*x^2 - 2*y^2 + 2*x + 2*y
      on W: (t, u) ↦ 2*t*u + 2*t
      sage: s = v.restrict(U)(f.restrict(V)) ; s
      Scalar field v(f) on the Open subset W of the 2-dimensional
       differentiable manifold M
      sage: s.display()
      v(f): W → ℝ
         (x, y) ↦ 2*x^2 - 2*y^2 + 2*x + 2*y
         (t, u) ↦ 2*t*u + 2*t

  Python

      >>> from sage.all import *
      >>> s = v(f.restrict(U)) ; s
      Scalar field v(f) on the Open subset U of the 2-dimensional
       differentiable manifold M
      >>> s == v(f).restrict(U)
      True
      >>> s = v(f.restrict(W)) ; s
      Scalar field v(f) on the Open subset W of the 2-dimensional
       differentiable manifold M
      >>> s.display()
      v(f): W → ℝ
         (x, y) ↦ 2*x^2 - 2*y^2 + 2*x + 2*y
         (t, u) ↦ 2*t*u + 2*t
      >>> s = v.restrict(U)(f) ; s
      Scalar field v(f) on the Open subset U of the 2-dimensional
       differentiable manifold M
      >>> s.display()
      v(f): U → ℝ
         (x, y) ↦ 2*x^2 - 2*y^2 + 2*x + 2*y
      on W: (t, u) ↦ 2*t*u + 2*t
      >>> s = v.restrict(U)(f.restrict(V)) ; s
      Scalar field v(f) on the Open subset W of the 2-dimensional
       differentiable manifold M
      >>> s.display()
      v(f): W → ℝ
         (x, y) ↦ 2*x^2 - 2*y^2 + 2*x + 2*y
         (t, u) ↦ 2*t*u + 2*t

  bracket(other)

    Return the Lie bracket `[self, other]`.

    INPUT:

    - `other` – a `VectorField`

    OUTPUT: the `VectorField` `[self, other]`

    EXAMPLES:

    Sage

        sage: M = Manifold(3, 'M')
        sage: X.<x,y,z> = M.chart()
        sage: v = -X.frame()[0] + 2*X.frame()[1] - (x^2 - y)*X.frame()[2]
        sage: w = (z + y) * X.frame()[1] - X.frame()[2]
        sage: vw = v.bracket(w); vw
        Vector field on the 3-dimensional differentiable manifold M
        sage: vw.display()
        (-x^2 + y + 2) ∂/∂y + (-y - z) ∂/∂z

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'M')
        >>> X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3)
        >>> v = -X.frame()[Integer(0)] + Integer(2)*X.frame()[Integer(1)] - (x**Integer(2) - y)*X.frame()[Integer(2)]
        >>> w = (z + y) * X.frame()[Integer(1)] - X.frame()[Integer(2)]
        >>> vw = v.bracket(w); vw
        Vector field on the 3-dimensional differentiable manifold M
        >>> vw.display()
        (-x^2 + y + 2) ∂/∂y + (-y - z) ∂/∂z

    Some checks:

    Sage

        sage: vw == - w.bracket(v)
        True
        sage: f = M.scalar_field({X: x+y*z})
        sage: vw(f) == v(w(f)) - w(v(f))
        True
        sage: vw == w.lie_derivative(v)
        True

    [Python]

        >>> from sage.all import *
        >>> vw == - w.bracket(v)
        True
        >>> f = M.scalar_field({X: x+y*z})
        >>> vw(f) == v(w(f)) - w(v(f))
        True
        >>> vw == w.lie_derivative(v)
        True

  cross(other, metric=None)

    alias of `cross_product()`.

  cross_product(other, metric=None)

    Return the cross product of `self` with another vector field (with respect to a given metric), assuming that the domain of `self` is 3-dimensional.

    If `self` is a vector field \(u\) on a 3-dimensional differentiable orientable manifold \(M\) and `other` is a vector field \(v\) on \(M\), the cross product (also called vector product) of \(u\) by \(v\) with respect to a pseudo-Riemannian metric \(g\) on \(M\) is the vector field \(w = u\times v\) defined by

    \[w^i = \epsilon^i_{\phantom{i} jk} u^j v^k = g^{il} \epsilon_{ljk} u^j v^k\]

    where \(\epsilon\) is the volume 3-form (Levi-Civita tensor) of \(g\) (cf. `volume_form()`)

    Note

    The method `cross_product` is meaningful only if for vector fields on a 3-dimensional manifold.

    INPUT:

    - `other` – a vector field, defined on the same domain as `self`

    - `metric` – (default: `None`) the pseudo-Riemannian metric \(g\) involved in the definition of the cross product; if none is provided, the domain of `self` is supposed to be endowed with a default metric (i.e. is supposed to be pseudo-Riemannian manifold, see `PseudoRiemannianManifold`) and the latter is used to define the cross product

    OUTPUT:

    - instance of `VectorField` representing the cross product of `self` by `other`.

    EXAMPLES:

    Cross product in the Euclidean 3-space:

    Sage

        sage: M.<x,y,z> = EuclideanSpace()
        sage: u = M.vector_field(-y, x, 0, name='u')
        sage: v = M.vector_field(x, y, 0, name='v')
        sage: w = u.cross_product(v); w
        Vector field u x v on the Euclidean space E^3
        sage: w.display()
        u x v = (-x^2 - y^2) e_z

    Python

        >>> from sage.all import *
        >>> M = EuclideanSpace(names=('x', 'y', 'z',)); (x, y, z,) = M._first_ngens(3)
        >>> u = M.vector_field(-y, x, Integer(0), name='u')
        >>> v = M.vector_field(x, y, Integer(0), name='v')
        >>> w = u.cross_product(v); w
        Vector field u x v on the Euclidean space E^3
        >>> w.display()
        u x v = (-x^2 - y^2) e_z

    A shortcut alias of `cross_product` is `cross`:

    Sage

        sage: u.cross(v) == w
        True

    [Python]

        >>> from sage.all import *
        >>> u.cross(v) == w
        True

    The cross product of a vector field with itself is zero:

    Sage

        sage: u.cross_product(u).display()
        u x u = 0

    Python

        >>> from sage.all import *
        >>> u.cross_product(u).display()
        u x u = 0

    Cross product with respect to a metric that is not the default one:

    Sage

        sage: h = M.riemannian_metric('h')
        sage: h[1,1], h[2,2], h[3,3] = 1/(1+y^2), 1/(1+z^2), 1/(1+x^2)
        sage: w = u.cross_product(v, metric=h); w
        Vector field on the Euclidean space E^3
        sage: w.display()
        -(x^2 + y^2)*sqrt(x^2 + 1)/(sqrt(y^2 + 1)*sqrt(z^2 + 1)) e_z

    [Python]

        >>> from sage.all import *
        >>> h = M.riemannian_metric('h')
        >>> h[Integer(1),Integer(1)], h[Integer(2),Integer(2)], h[Integer(3),Integer(3)] = Integer(1)/(Integer(1)+y**Integer(2)), Integer(1)/(Integer(1)+z**Integer(2)), Integer(1)/(Integer(1)+x**Integer(2))
        >>> w = u.cross_product(v, metric=h); w
        Vector field on the Euclidean space E^3
        >>> w.display()
        -(x^2 + y^2)*sqrt(x^2 + 1)/(sqrt(y^2 + 1)*sqrt(z^2 + 1)) e_z

    Cross product of two vector fields along a curve (arc of a helix):

    Sage

        sage: R.<t> = manifolds.RealLine()
        sage: C = M.curve((cos(t), sin(t), t), (t, 0, 2*pi), name='C')
        sage: u = C.tangent_vector_field()
        sage: u.display()
        C' = -sin(t) e_x + cos(t) e_y + e_z
        sage: I = C.domain(); I
        Real interval (0, 2*pi)
        sage: v = I.vector_field(-cos(t), sin(t), 0, dest_map=C)
        sage: v.display()
        -cos(t) e_x + sin(t) e_y
        sage: w = u.cross_product(v); w
        Vector field along the Real interval (0, 2*pi) with values on the
         Euclidean space E^3
        sage: w.parent().destination_map()
        Curve C in the Euclidean space E^3
        sage: w.display()
        -sin(t) e_x - cos(t) e_y + (2*cos(t)^2 - 1) e_z

    Python

        >>> from sage.all import *
        >>> R = manifolds.RealLine(names=('t',)); (t,) = R._first_ngens(1)
        >>> C = M.curve((cos(t), sin(t), t), (t, Integer(0), Integer(2)*pi), name='C')
        >>> u = C.tangent_vector_field()
        >>> u.display()
        C' = -sin(t) e_x + cos(t) e_y + e_z
        >>> I = C.domain(); I
        Real interval (0, 2*pi)
        >>> v = I.vector_field(-cos(t), sin(t), Integer(0), dest_map=C)
        >>> v.display()
        -cos(t) e_x + sin(t) e_y
        >>> w = u.cross_product(v); w
        Vector field along the Real interval (0, 2*pi) with values on the
         Euclidean space E^3
        >>> w.parent().destination_map()
        Curve C in the Euclidean space E^3
        >>> w.display()
        -sin(t) e_x - cos(t) e_y + (2*cos(t)^2 - 1) e_z

    Cross product between a vector field along the curve and a vector field on the ambient Euclidean space:

    Sage

        sage: e_x = M.cartesian_frame()[1]
        sage: w = u.cross_product(e_x); w
        Vector field C' x e_x along the Real interval (0, 2*pi) with values
         on the Euclidean space E^3
        sage: w.display()
        C' x e_x = e_y - cos(t) e_z

    [Python]

        >>> from sage.all import *
        >>> e_x = M.cartesian_frame()[Integer(1)]
        >>> w = u.cross_product(e_x); w
        Vector field C' x e_x along the Real interval (0, 2*pi) with values
         on the Euclidean space E^3
        >>> w.display()
        C' x e_x = e_y - cos(t) e_z

  curl(metric=None)

    Return the curl of `self` with respect to a given metric, assuming that the domain of `self` is 3-dimensional.

    If `self` is a vector field \(v\) on a 3-dimensional differentiable orientable manifold \(M\), the curl of \(v\) with respect to a metric \(g\) on \(M\) is the vector field defined by

    \[\mathrm{curl}\, v = (*(\mathrm{d} v^\flat))^\sharp\]

    where \(v^\flat\) is the 1-form associated to \(v\) by the metric \(g\) (see `down()`), \(*(\mathrm{d} v^\flat)\) is the Hodge dual with respect to \(g\) of the 2-form \(\mathrm{d} v^\flat\) (exterior derivative of \(v^\flat\)) (see `hodge_dual()`) and \((*(\mathrm{d} v^\flat))^\sharp\) is corresponding vector field by \(g\)-duality (see `up()`).

    An alternative expression of the curl is

    \[(\mathrm{curl}\, v)^i = \epsilon^{ijk} \nabla_j v_k\]

    where \(\nabla\) is the Levi-Civita connection of \(g\) (cf. `LeviCivitaConnection`) and \(\epsilon\) the volume 3-form (Levi-Civita tensor) of \(g\) (cf. `volume_form()`)

    Note

    The method `curl` is meaningful only if `self` is a vector field on a 3-dimensional manifold.

    INPUT:

    - `metric` – (default: `None`) the pseudo-Riemannian metric \(g\) involved in the definition of the curl; if none is provided, the domain of `self` is supposed to be endowed with a default metric (i.e. is supposed to be pseudo-Riemannian manifold, see `PseudoRiemannianManifold`) and the latter is used to define the curl

    OUTPUT: instance of `VectorField` representing the curl of `self`

    EXAMPLES:

    Curl of a vector field in the Euclidean 3-space:

    Sage

        sage: M.<x,y,z> = EuclideanSpace()
        sage: v = M.vector_field(-y, x, 0, name='v')
        sage: v.display()
        v = -y e_x + x e_y
        sage: s = v.curl(); s
        Vector field curl(v) on the Euclidean space E^3
        sage: s.display()
        curl(v) = 2 e_z

    Python

        >>> from sage.all import *
        >>> M = EuclideanSpace(names=('x', 'y', 'z',)); (x, y, z,) = M._first_ngens(3)
        >>> v = M.vector_field(-y, x, Integer(0), name='v')
        >>> v.display()
        v = -y e_x + x e_y
        >>> s = v.curl(); s
        Vector field curl(v) on the Euclidean space E^3
        >>> s.display()
        curl(v) = 2 e_z

    The function `curl()` from the `operators` module can be used instead of the method `curl()`:

    Sage

        sage: from sage.manifolds.operators import curl
        sage: curl(v) == s
        True

    [Python]

        >>> from sage.all import *
        >>> from sage.manifolds.operators import curl
        >>> curl(v) == s
        True

    If one prefers the notation `rot` over `curl`, it suffices to do:

    Sage

        sage: from sage.manifolds.operators import curl as rot
        sage: rot(v) == s
        True

    Python

        >>> from sage.all import *
        >>> from sage.manifolds.operators import curl as rot
        >>> rot(v) == s
        True

    The curl of a gradient vanishes identically:

    Sage

        sage: f = M.scalar_field(function('F')(x,y,z))
        sage: gradf = f.gradient()
        sage: gradf.display()
        d(F)/dx e_x + d(F)/dy e_y + d(F)/dz e_z
        sage: s = curl(gradf); s
        Vector field on the Euclidean space E^3
        sage: s.display()
        0

    [Python]

        >>> from sage.all import *
        >>> f = M.scalar_field(function('F')(x,y,z))
        >>> gradf = f.gradient()
        >>> gradf.display()
        d(F)/dx e_x + d(F)/dy e_y + d(F)/dz e_z
        >>> s = curl(gradf); s
        Vector field on the Euclidean space E^3
        >>> s.display()
        0

  dot(other, metric=None)

    alias of `dot_product()`.

  dot_product(other, metric=None)

    Return the scalar product of `self` with another vector field (with respect to a given metric).

    If `self` is the vector field \(u\) and other is the vector field \(v\), the scalar product of \(u\) by \(v\) with respect to a given pseudo-Riemannian metric \(g\) is the scalar field \(s\) defined by

    \[s = u\cdot v = g(u,v) = g_{ij} u^i v^j\]

    INPUT:

    - `other` – a vector field, defined on the same domain as `self`

    - `metric` – (default: `None`) the pseudo-Riemannian metric \(g\) involved in the definition of the scalar product; if none is provided, the domain of `self` is supposed to be endowed with a default metric (i.e. is supposed to be pseudo-Riemannian manifold, see `PseudoRiemannianManifold`) and the latter is used to define the scalar product

    OUTPUT:

    - instance of `DiffScalarField` representing the scalar product of `self` by `other`.

    EXAMPLES:

    Scalar product in the Euclidean plane:

    Sage

        sage: M.<x,y> = EuclideanSpace()
        sage: u = M.vector_field(x, y, name='u')
        sage: v = M.vector_field(y, x, name='v')
        sage: s = u.dot_product(v); s
        Scalar field u.v on the Euclidean plane E^2
        sage: s.display()
        u.v: E^2 → ℝ
           (x, y) ↦ 2*x*y

    Python

        >>> from sage.all import *
        >>> M = EuclideanSpace(names=('x', 'y',)); (x, y,) = M._first_ngens(2)
        >>> u = M.vector_field(x, y, name='u')
        >>> v = M.vector_field(y, x, name='v')
        >>> s = u.dot_product(v); s
        Scalar field u.v on the Euclidean plane E^2
        >>> s.display()
        u.v: E^2 → ℝ
           (x, y) ↦ 2*x*y

    A shortcut alias of `dot_product` is `dot`:

    Sage

        sage: u.dot(v) == s
        True

    [Python]

        >>> from sage.all import *
        >>> u.dot(v) == s
        True

    A test of orthogonality:

    Sage

        sage: v[:] = -y, x
        sage: u.dot_product(v) == 0
        True

    Python

        >>> from sage.all import *
        >>> v[:] = -y, x
        >>> u.dot_product(v) == Integer(0)
        True

    Scalar product with respect to a metric that is not the default one:

    Sage

        sage: h = M.riemannian_metric('h')
        sage: h[1,1], h[2,2] = 1/(1+y^2), 1/(1+x^2)
        sage: s = u.dot_product(v, metric=h); s
        Scalar field h(u,v) on the Euclidean plane E^2
        sage: s.display()
        h(u,v): E^2 → ℝ
           (x, y) ↦ -(x^3*y - x*y^3)/((x^2 + 1)*y^2 + x^2 + 1)

    [Python]

        >>> from sage.all import *
        >>> h = M.riemannian_metric('h')
        >>> h[Integer(1),Integer(1)], h[Integer(2),Integer(2)] = Integer(1)/(Integer(1)+y**Integer(2)), Integer(1)/(Integer(1)+x**Integer(2))
        >>> s = u.dot_product(v, metric=h); s
        Scalar field h(u,v) on the Euclidean plane E^2
        >>> s.display()
        h(u,v): E^2 → ℝ
           (x, y) ↦ -(x^3*y - x*y^3)/((x^2 + 1)*y^2 + x^2 + 1)

    Scalar product of two vector fields along a curve (a lemniscate of Gerono):

    Sage

        sage: R.<t> = manifolds.RealLine()
        sage: C = M.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='C')
        sage: u = C.tangent_vector_field(name='u')
        sage: u.display()
        u = cos(t) e_x + (2*cos(t)^2 - 1) e_y
        sage: I = C.domain(); I
        Real interval (0, 2*pi)
        sage: v = I.vector_field(cos(t), -1, dest_map=C, name='v')
        sage: v.display()
        v = cos(t) e_x - e_y
        sage: s = u.dot_product(v); s
        Scalar field u.v on the Real interval (0, 2*pi)
        sage: s.display()
        u.v: (0, 2*pi) → ℝ
           t ↦ sin(t)^2

    Python

        >>> from sage.all import *
        >>> R = manifolds.RealLine(names=('t',)); (t,) = R._first_ngens(1)
        >>> C = M.curve([sin(t), sin(Integer(2)*t)/Integer(2)], (t, Integer(0), Integer(2)*pi), name='C')
        >>> u = C.tangent_vector_field(name='u')
        >>> u.display()
        u = cos(t) e_x + (2*cos(t)^2 - 1) e_y
        >>> I = C.domain(); I
        Real interval (0, 2*pi)
        >>> v = I.vector_field(cos(t), -Integer(1), dest_map=C, name='v')
        >>> v.display()
        v = cos(t) e_x - e_y
        >>> s = u.dot_product(v); s
        Scalar field u.v on the Real interval (0, 2*pi)
        >>> s.display()
        u.v: (0, 2*pi) → ℝ
           t ↦ sin(t)^2

    Scalar product between a vector field along the curve and a vector field on the ambient Euclidean plane:

    Sage

        sage: e_x = M.cartesian_frame()[1]
        sage: s = u.dot_product(e_x); s
        Scalar field u.e_x on the Real interval (0, 2*pi)
        sage: s.display()
        u.e_x: (0, 2*pi) → ℝ
           t ↦ cos(t)

    [Python]

        >>> from sage.all import *
        >>> e_x = M.cartesian_frame()[Integer(1)]
        >>> s = u.dot_product(e_x); s
        Scalar field u.e_x on the Real interval (0, 2*pi)
        >>> s.display()
        u.e_x: (0, 2*pi) → ℝ
           t ↦ cos(t)

  norm(metric=None)

    Return the norm of `self` (with respect to a given metric).

    The norm of a vector field \(v\) with respect to a given pseudo-Riemannian metric \(g\) is the scalar field \(\|v\|\) defined by

    \[\|v\| = \sqrt{g(v,v)}\]

    Note

    If the metric \(g\) is not positive definite, it may be that \(\|v\|\) takes imaginary values.

    INPUT:

    - `metric` – (default: `None`) the pseudo-Riemannian metric \(g\) involved in the definition of the norm; if none is provided, the domain of `self` is supposed to be endowed with a default metric (i.e. is supposed to be pseudo-Riemannian manifold, see `PseudoRiemannianManifold`) and the latter is used to define the norm

    OUTPUT:

    - instance of `DiffScalarField` representing the norm of `self`.

    EXAMPLES:

    Norm in the Euclidean plane:

    Sage

        sage: M.<x,y> = EuclideanSpace()
        sage: v = M.vector_field(-y, x, name='v')
        sage: s = v.norm(); s
        Scalar field |v| on the Euclidean plane E^2
        sage: s.display()
        |v|: E^2 → ℝ
           (x, y) ↦ sqrt(x^2 + y^2)

    Python

        >>> from sage.all import *
        >>> M = EuclideanSpace(names=('x', 'y',)); (x, y,) = M._first_ngens(2)
        >>> v = M.vector_field(-y, x, name='v')
        >>> s = v.norm(); s
        Scalar field |v| on the Euclidean plane E^2
        >>> s.display()
        |v|: E^2 → ℝ
           (x, y) ↦ sqrt(x^2 + y^2)

    The global function `norm()` can be used instead of the method `norm()`:

    Sage

        sage: norm(v) == s
        True

    [Python]

        >>> from sage.all import *
        >>> norm(v) == s
        True

    Norm with respect to a metric that is not the default one:

    Sage

        sage: h = M.riemannian_metric('h')
        sage: h[1,1], h[2,2] = 1/(1+y^2), 1/(1+x^2)
        sage: s = v.norm(metric=h); s
        Scalar field |v|_h on the Euclidean plane E^2
        sage: s.display()
        |v|_h: E^2 → ℝ
           (x, y) ↦ sqrt((2*x^2 + 1)*y^2 + x^2)/(sqrt(x^2 + 1)*sqrt(y^2 + 1))

    Python

        >>> from sage.all import *
        >>> h = M.riemannian_metric('h')
        >>> h[Integer(1),Integer(1)], h[Integer(2),Integer(2)] = Integer(1)/(Integer(1)+y**Integer(2)), Integer(1)/(Integer(1)+x**Integer(2))
        >>> s = v.norm(metric=h); s
        Scalar field |v|_h on the Euclidean plane E^2
        >>> s.display()
        |v|_h: E^2 → ℝ
           (x, y) ↦ sqrt((2*x^2 + 1)*y^2 + x^2)/(sqrt(x^2 + 1)*sqrt(y^2 + 1))

    Norm of the tangent vector field to a curve (a lemniscate of Gerono):

    Sage

        sage: R.<t> = manifolds.RealLine()
        sage: C = M.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='C')
        sage: v = C.tangent_vector_field()
        sage: v.display()
        C' = cos(t) e_x + (2*cos(t)^2 - 1) e_y
        sage: s = v.norm(); s
        Scalar field |C'| on the Real interval (0, 2*pi)
        sage: s.display()
        |C'|: (0, 2*pi) → ℝ
           t ↦ sqrt(4*cos(t)^4 - 3*cos(t)^2 + 1)

    [Python]

        >>> from sage.all import *
        >>> R = manifolds.RealLine(names=('t',)); (t,) = R._first_ngens(1)
        >>> C = M.curve([sin(t), sin(Integer(2)*t)/Integer(2)], (t, Integer(0), Integer(2)*pi), name='C')
        >>> v = C.tangent_vector_field()
        >>> v.display()
        C' = cos(t) e_x + (2*cos(t)^2 - 1) e_y
        >>> s = v.norm(); s
        Scalar field |C'| on the Real interval (0, 2*pi)
        >>> s.display()
        |C'|: (0, 2*pi) → ℝ
           t ↦ sqrt(4*cos(t)^4 - 3*cos(t)^2 + 1)

  plot(chart=None, ambient_coords=None, mapping=None, chart_domain=None, fixed_coords=None, ranges=None, number_values=None, steps=None, parameters=None, label_axes=True, max_range=8, scale=1, color='blue', **extra_options)

    Plot the vector field in a Cartesian graph based on the coordinates of some ambient chart.

    The vector field is drawn in terms of two (2D graphics) or three (3D graphics) coordinates of a given chart, called hereafter the ambient chart. The vector field’s base points \(p\) (or their images \(\Phi(p)\) by some differentiable mapping \(\Phi\)) must lie in the ambient chart’s domain.

    INPUT:

    - `chart` – (default: `None`) the ambient chart (see above); if `None`, the default chart of the vector field’s domain is used

    - `ambient_coords` – (default: `None`) tuple containing the 2 or 3 coordinates of the ambient chart in terms of which the plot is performed; if `None`, all the coordinates of the ambient chart are considered

    - `mapping` – `DiffMap` (default: `None`); differentiable map \(\Phi\) providing the link between the vector field’s domain and the ambient chart `chart`; if `None`, the identity map is assumed

    - `chart_domain` – (default: `None`) chart on the vector field’s domain to define the points at which vector arrows are to be plotted; if `None`, the default chart of the vector field’s domain is used

    - `fixed_coords` – (default: `None`) dictionary with keys the coordinates of `chart_domain` that are kept fixed and with values the value of these coordinates; if `None`, all the coordinates of `chart_domain` are used

    - `ranges` – (default: `None`) dictionary with keys the coordinates of `chart_domain` to be used and values tuples `(x_min, x_max)` specifying the coordinate range for the plot; if `None`, the entire coordinate range declared during the construction of `chart_domain` is considered (with `-Infinity` replaced by `-max_range` and `+Infinity` by `max_range`)

    - `number_values` – (default: `None`) either an integer or a dictionary with keys the coordinates of `chart_domain` to be used and values the number of values of the coordinate for sampling the part of the vector field’s domain involved in the plot ; if `number_values` is a single integer, it represents the number of values for all coordinates; if `number_values` is `None`, it is set to 9 for a 2D plot and to 5 for a 3D plot

    - `steps` – (default: `None`) dictionary with keys the coordinates of `chart_domain` to be used and values the step between each constant value of the coordinate; if `None`, the step is computed from the coordinate range (specified in `ranges`) and `number_values`; on the contrary, if the step is provided for some coordinate, the corresponding number of values is deduced from it and the coordinate range

    - `parameters` – (default: `None`) dictionary giving the numerical values of the parameters that may appear in the coordinate expression of the vector field (see example below)

    - `label_axes` – boolean (default: `True`); determining whether the labels of the coordinate axes of `chart` shall be added to the graph; can be set to `False` if the graph is 3D and must be superposed with another graph

    - `color` – (default: `'blue'`) color of the arrows representing the vectors

    - `max_range` – (default: 8) numerical value substituted to `+Infinity` if the latter is the upper bound of the range of a coordinate for which the plot is performed over the entire coordinate range (i.e. for which no specific plot range has been set in `ranges`); similarly `-max_range` is the numerical valued substituted for `-Infinity`

    - `scale` – (default: 1) value by which the lengths of the arrows representing the vectors is multiplied

    - `**extra_options` – extra options for the arrow plot, like `linestyle`, `width` or `arrowsize` (see `arrow2d()` and `arrow3d()` for details)

    OUTPUT:

    - a graphic object, either an instance of `Graphics` for a 2D plot (i.e. based on 2 coordinates of `chart`) or an instance of `Graphics3d` for a 3D plot (i.e. based on 3 coordinates of `chart`)

    EXAMPLES:

    Plot of a vector field on a 2-dimensional manifold:

    Sage

        sage: M = Manifold(2, 'M')
        sage: X.<x,y> = M.chart()
        sage: v = M.vector_field(-y, x, name='v')
        sage: v.display()
        v = -y ∂/∂x + x ∂/∂y
        sage: v.plot()                                                              # needs sage.plot
        Graphics object consisting of 80 graphics primitives

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M')
        >>> X = M.chart(names=('x', 'y',)); (x, y,) = X._first_ngens(2)
        >>> v = M.vector_field(-y, x, name='v')
        >>> v.display()
        v = -y ∂/∂x + x ∂/∂y
        >>> v.plot()                                                              # needs sage.plot
        Graphics object consisting of 80 graphics primitives

    Plot with various options:

    Sage

        sage: v.plot(scale=0.5, color='green', linestyle='--', width=1,             # needs sage.plot
        ....:        arrowsize=6)
        Graphics object consisting of 80 graphics primitives

    [Python]

        >>> from sage.all import *
        >>> v.plot(scale=RealNumber('0.5'), color='green', linestyle='--', width=Integer(1),             # needs sage.plot
        ...        arrowsize=Integer(6))
        Graphics object consisting of 80 graphics primitives

    Sage

        sage: v.plot(max_range=4, number_values=5, scale=0.5)                       # needs sage.plot
        Graphics object consisting of 24 graphics primitives

    Python

        >>> from sage.all import *
        >>> v.plot(max_range=Integer(4), number_values=Integer(5), scale=RealNumber('0.5'))                       # needs sage.plot
        Graphics object consisting of 24 graphics primitives

    Plot using parallel computation:

    Sage

        sage: Parallelism().set(nproc=2)
        sage: v.plot(scale=0.5,  number_values=10, linestyle='--', width=1,         # needs sage.plot
        ....:        arrowsize=6)
        Graphics object consisting of 100 graphics primitives

    [Python]

        >>> from sage.all import *
        >>> Parallelism().set(nproc=Integer(2))
        >>> v.plot(scale=RealNumber('0.5'),  number_values=Integer(10), linestyle='--', width=Integer(1),         # needs sage.plot
        ...        arrowsize=Integer(6))
        Graphics object consisting of 100 graphics primitives

    Sage

        sage: Parallelism().set(nproc=1)  # switch off parallelization

    Python

        >>> from sage.all import *
        >>> Parallelism().set(nproc=Integer(1))  # switch off parallelization

    Plots along a line of fixed coordinate:

    Sage

        sage: v.plot(fixed_coords={x: -2})                                          # needs sage.plot
        Graphics object consisting of 9 graphics primitives

    [Python]

        >>> from sage.all import *
        >>> v.plot(fixed_coords={x: -Integer(2)})                                          # needs sage.plot
        Graphics object consisting of 9 graphics primitives

    Sage

        sage: v.plot(fixed_coords={y: 1})                                           # needs sage.plot
        Graphics object consisting of 9 graphics primitives

    Python

        >>> from sage.all import *
        >>> v.plot(fixed_coords={y: Integer(1)})                                           # needs sage.plot
        Graphics object consisting of 9 graphics primitives

    Let us now consider a vector field on a 4-dimensional manifold:

    Sage

        sage: M = Manifold(4, 'M')
        sage: X.<t,x,y,z> = M.chart()
        sage: v = M.vector_field((t/8)^2, -t*y/4, t*x/4, t*z/4, name='v')
        sage: v.display()
        v = 1/64*t^2 ∂/∂t - 1/4*t*y ∂/∂x + 1/4*t*x ∂/∂y + 1/4*t*z ∂/∂z

    [Python]

        >>> from sage.all import *
        >>> M = Manifold(Integer(4), 'M')
        >>> X = M.chart(names=('t', 'x', 'y', 'z',)); (t, x, y, z,) = X._first_ngens(4)
        >>> v = M.vector_field((t/Integer(8))**Integer(2), -t*y/Integer(4), t*x/Integer(4), t*z/Integer(4), name='v')
        >>> v.display()
        v = 1/64*t^2 ∂/∂t - 1/4*t*y ∂/∂x + 1/4*t*x ∂/∂y + 1/4*t*z ∂/∂z

    We cannot make a 4D plot directly:

    Sage

        sage: v.plot()
        Traceback (most recent call last):
        ...
        ValueError: the number of ambient coordinates must be either 2 or 3, not 4

    Python

        >>> from sage.all import *
        >>> v.plot()
        Traceback (most recent call last):
        ...
        ValueError: the number of ambient coordinates must be either 2 or 3, not 4

    Rather, we have to select some coordinates for the plot, via the argument `ambient_coords`. For instance, for a 3D plot:

    Sage

        sage: v.plot(ambient_coords=(x, y, z), fixed_coords={t: 1},         # long time, needs sage.plot
        ....:        number_values=4)
        Graphics3d Object

    [Python]

        >>> from sage.all import *
        >>> v.plot(ambient_coords=(x, y, z), fixed_coords={t: Integer(1)},         # long time, needs sage.plot
        ...        number_values=Integer(4))
        Graphics3d Object

    Sage

        sage: v.plot(ambient_coords=(x, y, t), fixed_coords={z: 0},         # long time, needs sage.plot
        ....:        ranges={x: (-2,2), y: (-2,2), t: (-1, 4)},
        ....:        number_values=4)
        Graphics3d Object

    Python

        >>> from sage.all import *
        >>> v.plot(ambient_coords=(x, y, t), fixed_coords={z: Integer(0)},         # long time, needs sage.plot
        ...        ranges={x: (-Integer(2),Integer(2)), y: (-Integer(2),Integer(2)), t: (-Integer(1), Integer(4))},
        ...        number_values=Integer(4))
        Graphics3d Object

    or, for a 2D plot:

    Sage

        sage: v.plot(ambient_coords=(x, y), fixed_coords={t: 1, z: 0})      # long time, needs sage.plot
        Graphics object consisting of 80 graphics primitives

    [Python]

        >>> from sage.all import *
        >>> v.plot(ambient_coords=(x, y), fixed_coords={t: Integer(1), z: Integer(0)})      # long time, needs sage.plot
        Graphics object consisting of 80 graphics primitives

    Sage

        sage: v.plot(ambient_coords=(x, t), fixed_coords={y: 1, z: 0})      # long time, needs sage.plot
        Graphics object consisting of 72 graphics primitives

    Python

        >>> from sage.all import *
        >>> v.plot(ambient_coords=(x, t), fixed_coords={y: Integer(1), z: Integer(0)})      # long time, needs sage.plot
        Graphics object consisting of 72 graphics primitives

    An example of plot via a differential mapping: plot of a vector field tangent to a 2-sphere viewed in \(\RR^3\):

    Sage

        sage: S2 = Manifold(2, 'S^2')
        sage: U = S2.open_subset('U') # the open set covered by spherical coord.
        sage: XS.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
        sage: R3 = Manifold(3, 'R^3')
        sage: X3.<x,y,z> = R3.chart()
        sage: F = S2.diff_map(R3, {(XS, X3): [sin(th)*cos(ph),
        ....:                       sin(th)*sin(ph), cos(th)]}, name='F')
        sage: F.display() # the standard embedding of S^2 into R^3
        F: S^2 → R^3
        on U: (th, ph) ↦ (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))
        sage: v = XS.frame()[1] ; v  # the coordinate vector ∂/∂phi
        Vector field ∂/∂ph on the Open subset U of the 2-dimensional
         differentiable manifold S^2
        sage: graph_v = v.plot(chart=X3, mapping=F, label_axes=False)               # needs sage.plot
        sage: graph_S2 = XS.plot(chart=X3, mapping=F, number_values=9)              # needs sage.plot
        sage: graph_v + graph_S2                                                    # needs sage.plot
        Graphics3d Object

    [Python]

        >>> from sage.all import *
        >>> S2 = Manifold(Integer(2), 'S^2')
        >>> U = S2.open_subset('U') # the open set covered by spherical coord.
        >>> XS = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi', names=('th', 'ph',)); (th, ph,) = XS._first_ngens(2)
        >>> R3 = Manifold(Integer(3), 'R^3')
        >>> X3 = R3.chart(names=('x', 'y', 'z',)); (x, y, z,) = X3._first_ngens(3)
        >>> F = S2.diff_map(R3, {(XS, X3): [sin(th)*cos(ph),
        ...                       sin(th)*sin(ph), cos(th)]}, name='F')
        >>> F.display() # the standard embedding of S^2 into R^3
        F: S^2 → R^3
        on U: (th, ph) ↦ (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))
        >>> v = XS.frame()[Integer(1)] ; v  # the coordinate vector ∂/∂phi
        Vector field ∂/∂ph on the Open subset U of the 2-dimensional
         differentiable manifold S^2
        >>> graph_v = v.plot(chart=X3, mapping=F, label_axes=False)               # needs sage.plot
        >>> graph_S2 = XS.plot(chart=X3, mapping=F, number_values=Integer(9))              # needs sage.plot
        >>> graph_v + graph_S2                                                    # needs sage.plot
        Graphics3d Object

    Note that the default values of some arguments of the method `plot` are stored in the dictionary `plot.options`:

    Sage

        sage: v.plot.options  # random (dictionary output)
        {'color': 'blue', 'max_range': 8, 'scale': 1}

    Python

        >>> from sage.all import *
        >>> v.plot.options  # random (dictionary output)
        {'color': 'blue', 'max_range': 8, 'scale': 1}

    so that they can be adjusted by the user:

    Sage

        sage: v.plot.options['color'] = 'red'

    [Python]

        >>> from sage.all import *
        >>> v.plot.options['color'] = 'red'

    From now on, all plots of vector fields will use red as the default color. To restore the original default options, it suffices to type:

    Sage

        sage: v.plot.reset()

    Python

        >>> from sage.all import *
        >>> v.plot.reset()

class sage.manifolds.differentiable.vectorfield.VectorFieldParal(vector_field_module, name=None, latex_name=None)

  Bases: `FiniteRankFreeModuleElement`, `MultivectorFieldParal`, `VectorField`

  Vector field along a differentiable manifold, with values on a parallelizable manifold.

  An instance of this class is a vector field along a differentiable manifold \(U\) with values on a parallelizable manifold \(M\), via a differentiable map \(\Phi: U \rightarrow M\). More precisely, given a differentiable map

  \[\Phi:\ U \longrightarrow M,\]

  a vector field along \(U\) with values on \(M\) is a differentiable map

  \[v:\ U \longrightarrow TM\]

  (\(TM\) being the tangent bundle of \(M\)) such that

  \[\forall p \in U,\ v(p) \in T_{\Phi(p)}M.\]

  The standard case of vector fields 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\)).

  Note

  If \(M\) is not parallelizable, then `VectorField` must be used instead.

  INPUT:

  - `vector_field_module` – free module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(M\supset\Phi(U)\)

  - `name` – (default: `None`) name given to the vector field

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

  EXAMPLES:

  A vector field on a parallelizable 3-dimensional manifold:

  Sage

      sage: M = Manifold(3, 'M')
      sage: c_xyz.<x,y,z> = M.chart()
      sage: v = M.vector_field(name='V') ; v
      Vector field V on the 3-dimensional differentiable manifold M
      sage: latex(v)
      V

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(3), 'M')
      >>> c_xyz = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = c_xyz._first_ngens(3)
      >>> v = M.vector_field(name='V') ; v
      Vector field V on the 3-dimensional differentiable manifold M
      >>> latex(v)
      V

  Vector fields are considered as elements of a module over the ring (algebra) of scalar fields on \(M\):

  Sage

      sage: v.parent()
      Free module X(M) of vector fields on the 3-dimensional differentiable
       manifold M
      sage: v.parent().base_ring()
      Algebra of differentiable scalar fields on the 3-dimensional
       differentiable manifold M
      sage: v.parent() is M.vector_field_module()
      True

  [Python]

      >>> from sage.all import *
      >>> v.parent()
      Free module X(M) of vector fields on the 3-dimensional differentiable
       manifold M
      >>> v.parent().base_ring()
      Algebra of differentiable scalar fields on the 3-dimensional
       differentiable manifold M
      >>> v.parent() is M.vector_field_module()
      True

  A vector field is a tensor field of rank 1 and of type \((1,0)\):

  Sage

      sage: v.tensor_rank()
      1
      sage: v.tensor_type()
      (1, 0)

  Python

      >>> from sage.all import *
      >>> v.tensor_rank()
      1
      >>> v.tensor_type()
      (1, 0)

  Components of a vector field with respect to a given frame:

  Sage

      sage: e = M.vector_frame('e') ; M.set_default_frame(e)
      sage: v[0], v[1], v[2] = (1+y, 4*x*z, 9)  # components on M's default frame (e)
      sage: v.comp()
      1-index components w.r.t. Vector frame (M, (e_0,e_1,e_2))

  [Python]

      >>> from sage.all import *
      >>> e = M.vector_frame('e') ; M.set_default_frame(e)
      >>> v[Integer(0)], v[Integer(1)], v[Integer(2)] = (Integer(1)+y, Integer(4)*x*z, Integer(9))  # components on M's default frame (e)
      >>> v.comp()
      1-index components w.r.t. Vector frame (M, (e_0,e_1,e_2))

  The totality of the components are accessed via the operator `[:]`:

  Sage

      sage: v[:] = (1+y, 4*x*z, 9)
      sage: v[:]
      [y + 1, 4*x*z, 9]

  Python

      >>> from sage.all import *
      >>> v[:] = (Integer(1)+y, Integer(4)*x*z, Integer(9))
      >>> v[:]
      [y + 1, 4*x*z, 9]

  The components are also read on the expansion on the frame `e`, as provided by the method `display()`:

  Sage

      sage: v.display()  # expansion in the default frame
      V = (y + 1) e_0 + 4*x*z e_1 + 9 e_2

  [Python]

      >>> from sage.all import *
      >>> v.display()  # expansion in the default frame
      V = (y + 1) e_0 + 4*x*z e_1 + 9 e_2

  A subset of the components can be accessed by using slice notation:

  Sage

      sage: v[1:] = (-2, -x*y)
      sage: v[:]
      [y + 1, -2, -x*y]
      sage: v[:2]
      [y + 1, -2]

  Python

      >>> from sage.all import *
      >>> v[Integer(1):] = (-Integer(2), -x*y)
      >>> v[:]
      [y + 1, -2, -x*y]
      >>> v[:Integer(2)]
      [y + 1, -2]

  Components in another frame:

  Sage

      sage: f = M.vector_frame('f')
      sage: for i in range(3):
      ....:     v.set_comp(f)[i] = (i+1)**3 * c_xyz[i]
      sage: v.comp(f)[2]
      27*z
      sage: v[f, 2]  # equivalent to above
      27*z
      sage: v.display(f)
      V = x f_0 + 8*y f_1 + 27*z f_2

  [Python]

      >>> from sage.all import *
      >>> f = M.vector_frame('f')
      >>> for i in range(Integer(3)):
      ...     v.set_comp(f)[i] = (i+Integer(1))**Integer(3) * c_xyz[i]
      >>> v.comp(f)[Integer(2)]
      27*z
      >>> v[f, Integer(2)]  # equivalent to above
      27*z
      >>> v.display(f)
      V = x f_0 + 8*y f_1 + 27*z f_2

  One can set the components at the vector definition:

  Sage

      sage: v = M.vector_field(1+y, 4*x*z, 9, name='V')
      sage: v.display()
      V = (y + 1) e_0 + 4*x*z e_1 + 9 e_2

  Python

      >>> from sage.all import *
      >>> v = M.vector_field(Integer(1)+y, Integer(4)*x*z, Integer(9), name='V')
      >>> v.display()
      V = (y + 1) e_0 + 4*x*z e_1 + 9 e_2

  If the components regard a vector frame different from the default one, the vector frame has to be specified via the argument `frame`:

  Sage

      sage: v = M.vector_field(x, 8*y, 27*z, frame=f, name='V')
      sage: v.display(f)
      V = x f_0 + 8*y f_1 + 27*z f_2

  [Python]

      >>> from sage.all import *
      >>> v = M.vector_field(x, Integer(8)*y, Integer(27)*z, frame=f, name='V')
      >>> v.display(f)
      V = x f_0 + 8*y f_1 + 27*z f_2

  For providing the components in various frames, one may use a dictionary:

  Sage

      sage: v = M.vector_field({e: [1+y, -2, -x*y], f: [x, 8*y, 27*z]},
      ....:                    name='V')
      sage: v.display(e)
      V = (y + 1) e_0 - 2 e_1 - x*y e_2
      sage: v.display(f)
      V = x f_0 + 8*y f_1 + 27*z f_2

  Python

      >>> from sage.all import *
      >>> v = M.vector_field({e: [Integer(1)+y, -Integer(2), -x*y], f: [x, Integer(8)*y, Integer(27)*z]},
      ...                    name='V')
      >>> v.display(e)
      V = (y + 1) e_0 - 2 e_1 - x*y e_2
      >>> v.display(f)
      V = x f_0 + 8*y f_1 + 27*z f_2

  It is also possible to construct a vector field from a vector of symbolic expressions (or any other iterable):

  Sage

      sage: v = M.vector_field(vector([1+y, 4*x*z, 9]), name='V')
      sage: v.display()
      V = (y + 1) e_0 + 4*x*z e_1 + 9 e_2

  [Python]

      >>> from sage.all import *
      >>> v = M.vector_field(vector([Integer(1)+y, Integer(4)*x*z, Integer(9)]), name='V')
      >>> v.display()
      V = (y + 1) e_0 + 4*x*z e_1 + 9 e_2

  The range of the indices depends on the convention set for the manifold:

  Sage

      sage: M = Manifold(3, 'M', start_index=1)
      sage: c_xyz.<x,y,z> = M.chart()
      sage: e = M.vector_frame('e') ; M.set_default_frame(e)
      sage: v = M.vector_field(1+y, 4*x*z, 9, name='V')
      sage: v[0]
      Traceback (most recent call last):
      ...
      IndexError: index out of range: 0 not in [1, 3]
      sage: v[1]  # OK
      y + 1

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(3), 'M', start_index=Integer(1))
      >>> c_xyz = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = c_xyz._first_ngens(3)
      >>> e = M.vector_frame('e') ; M.set_default_frame(e)
      >>> v = M.vector_field(Integer(1)+y, Integer(4)*x*z, Integer(9), name='V')
      >>> v[Integer(0)]
      Traceback (most recent call last):
      ...
      IndexError: index out of range: 0 not in [1, 3]
      >>> v[Integer(1)]  # OK
      y + 1

  A vector field acts on scalar fields (derivation along the vector field):

  Sage

      sage: M = Manifold(2, 'M')
      sage: c_cart.<x,y> = M.chart()
      sage: f = M.scalar_field(x*y^2, name='f')
      sage: v = M.vector_field(-y, x, name='v')
      sage: v.display()
      v = -y ∂/∂x + x ∂/∂y
      sage: v(f)
      Scalar field v(f) on the 2-dimensional differentiable manifold M
      sage: v(f).expr()
      2*x^2*y - y^3
      sage: latex(v(f))
      v\left(f\right)

  [Python]

      >>> from sage.all import *
      >>> M = Manifold(Integer(2), 'M')
      >>> c_cart = M.chart(names=('x', 'y',)); (x, y,) = c_cart._first_ngens(2)
      >>> f = M.scalar_field(x*y**Integer(2), name='f')
      >>> v = M.vector_field(-y, x, name='v')
      >>> v.display()
      v = -y ∂/∂x + x ∂/∂y
      >>> v(f)
      Scalar field v(f) on the 2-dimensional differentiable manifold M
      >>> v(f).expr()
      2*x^2*y - y^3
      >>> latex(v(f))
      v\left(f\right)

  Example of a vector field associated with a non-trivial map \(\Phi\); a vector field along a curve in \(M\):

  Sage

      sage: R = Manifold(1, 'R')
      sage: T.<t> = R.chart()  # canonical chart on R
      sage: Phi = R.diff_map(M, [cos(t), sin(t)], name='Phi') ; Phi
      Differentiable map Phi from the 1-dimensional differentiable manifold R
       to the 2-dimensional differentiable manifold M
      sage: Phi.display()
      Phi: R → M
         t ↦ (x, y) = (cos(t), sin(t))
      sage: w = R.vector_field(-sin(t), cos(t), dest_map=Phi, name='w') ; w
      Vector field w along the 1-dimensional differentiable manifold R with
       values on the 2-dimensional differentiable manifold M
      sage: w.parent()
      Free module X(R,Phi) of vector fields along the 1-dimensional
       differentiable manifold R mapped into the 2-dimensional differentiable
       manifold M
      sage: w.display()
      w = -sin(t) ∂/∂x + cos(t) ∂/∂y

  Python

      >>> from sage.all import *
      >>> R = Manifold(Integer(1), 'R')
      >>> T = R.chart(names=('t',)); (t,) = T._first_ngens(1)# canonical chart on R
      >>> Phi = R.diff_map(M, [cos(t), sin(t)], name='Phi') ; Phi
      Differentiable map Phi from the 1-dimensional differentiable manifold R
       to the 2-dimensional differentiable manifold M
      >>> Phi.display()
      Phi: R → M
         t ↦ (x, y) = (cos(t), sin(t))
      >>> w = R.vector_field(-sin(t), cos(t), dest_map=Phi, name='w') ; w
      Vector field w along the 1-dimensional differentiable manifold R with
       values on the 2-dimensional differentiable manifold M
      >>> w.parent()
      Free module X(R,Phi) of vector fields along the 1-dimensional
       differentiable manifold R mapped into the 2-dimensional differentiable
       manifold M
      >>> w.display()
      w = -sin(t) ∂/∂x + cos(t) ∂/∂y

  Value at a given point:

  Sage

      sage: p = R((0,), name='p') ; p
      Point p on the 1-dimensional differentiable manifold R
      sage: w.at(p)
      Tangent vector w at Point Phi(p) on the 2-dimensional differentiable
       manifold M
      sage: w.at(p).display()
      w = ∂/∂y
      sage: w.at(p) == v.at(Phi(p))
      True

  [Python]

      >>> from sage.all import *
      >>> p = R((Integer(0),), name='p') ; p
      Point p on the 1-dimensional differentiable manifold R
      >>> w.at(p)
      Tangent vector w at Point Phi(p) on the 2-dimensional differentiable
       manifold M
      >>> w.at(p).display()
      w = ∂/∂y
      >>> w.at(p) == v.at(Phi(p))
      True