Differentiable Scalar Fields¶
Given a differentiable manifold \(M\) of class \(C^k\) over a topological field \(K\) (in most applications, \(K = \RR\) or \(K = \CC\)), a differentiable scalar field on \(M\) is a map
of class \(C^k\).
Differentiable scalar fields are implemented by the class
DiffScalarField
.
AUTHORS:
 Eric Gourgoulhon, Michal Bejger (20132015): initial version
 Eric Gourgoulhon (2018): operators gradient, Laplacian and d’Alembertian
REFERENCES:

class
sage.manifolds.differentiable.scalarfield.
DiffScalarField
(parent, coord_expression=None, chart=None, name=None, latex_name=None)¶ Bases:
sage.manifolds.scalarfield.ScalarField
Differentiable scalar field on a differentiable manifold.
Given a differentiable manifold \(M\) of class \(C^k\) over a topological field \(K\) (in most applications, \(K = \RR\) or \(K = \CC\)), a differentiable scalar field defined on \(M\) is a map
\[f: M \longrightarrow K\]that is \(k\)times continuously differentiable.
The class
DiffScalarField
is a Sage element class, whose parent class isDiffScalarFieldAlgebra
. It inherits from the classScalarField
devoted to generic continuous scalar fields on topological manifolds.INPUT:
parent
– the algebra of scalar fields containing the scalar field (must be an instance of classDiffScalarFieldAlgebra
)coord_expression
– (default:None
) coordinate expression(s) of the scalar field; this can be either a dictionary of coordinate expressions in various charts on the domain, with the charts as keys;
 a single coordinate expression; if the argument
chart
is'all'
, this expression is set to all the charts defined on the open set; otherwise, the expression is set in the specific chart provided by the argumentchart
NB: If
coord_expression
isNone
or incomplete, coordinate expressions can be added after the creation of the object, by means of the methodsadd_expr()
,add_expr_by_continuation()
andset_expr()
chart
– (default:None
) chart defining the coordinates used incoord_expression
when the latter is a single coordinate expression; if none is provided (default), the default chart of the open set is assumed. Ifchart=='all'
,coord_expression
is assumed to be independent of the chart (constant scalar field).name
– (default:None
) string; name (symbol) given to the scalar fieldlatex_name
– (default:None
) string; LaTeX symbol to denote the scalar field; if none is provided, the LaTeX symbol is set toname
EXAMPLES:
A scalar field on the 2sphere:
sage: M = Manifold(2, 'M') # the 2dimensional sphere S^2 sage: U = M.open_subset('U') # complement of the North pole sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole sage: V = M.open_subset('V') # complement of the South pole sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole sage: M.declare_union(U,V) # S^2 is the union of U and V sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)), ....: intersection_name='W', ....: restrictions1= x^2+y^2!=0, ....: restrictions2= u^2+v^2!=0) sage: uv_to_xy = xy_to_uv.inverse() sage: f = M.scalar_field({c_xy: 1/(1+x^2+y^2), c_uv: (u^2+v^2)/(1+u^2+v^2)}, ....: name='f') ; f Scalar field f on the 2dimensional differentiable manifold M sage: f.display() f: M > R on U: (x, y) > 1/(x^2 + y^2 + 1) on V: (u, v) > (u^2 + v^2)/(u^2 + v^2 + 1)
For scalar fields defined by a single coordinate expression, the latter can be passed instead of the dictionary over the charts:
sage: g = U.scalar_field(x*y, chart=c_xy, name='g') ; g Scalar field g on the Open subset U of the 2dimensional differentiable manifold M
The above is indeed equivalent to:
sage: g = U.scalar_field({c_xy: x*y}, name='g') ; g Scalar field g on the Open subset U of the 2dimensional differentiable manifold M
Since
c_xy
is the default chart ofU
, the argumentchart
can be skipped:sage: g = U.scalar_field(x*y, name='g') ; g Scalar field g on the Open subset U of the 2dimensional differentiable manifold M
The scalar field \(g\) is defined on \(U\) and has an expression in terms of the coordinates \((u,v)\) on \(W=U\cap V\):
sage: g.display() g: U > R (x, y) > x*y on W: (u, v) > u*v/(u^4 + 2*u^2*v^2 + v^4)
Scalar fields on \(M\) can also be declared with a single chart:
sage: f = M.scalar_field(1/(1+x^2+y^2), chart=c_xy, name='f') ; f Scalar field f on the 2dimensional differentiable manifold M
Their definition must then be completed by providing the expressions on other charts, via the method
add_expr()
, to get a global cover of the manifold:sage: f.add_expr((u^2+v^2)/(1+u^2+v^2), chart=c_uv) sage: f.display() f: M > R on U: (x, y) > 1/(x^2 + y^2 + 1) on V: (u, v) > (u^2 + v^2)/(u^2 + v^2 + 1)
We can even first declare the scalar field without any coordinate expression and provide them subsequently:
sage: f = M.scalar_field(name='f') sage: f.add_expr(1/(1+x^2+y^2), chart=c_xy) sage: f.add_expr((u^2+v^2)/(1+u^2+v^2), chart=c_uv) sage: f.display() f: M > R on U: (x, y) > 1/(x^2 + y^2 + 1) on V: (u, v) > (u^2 + v^2)/(u^2 + v^2 + 1)
We may also use the method
add_expr_by_continuation()
to complete the coordinate definition using the analytic continuation from domains in which charts overlap:sage: f = M.scalar_field(1/(1+x^2+y^2), chart=c_xy, name='f') ; f Scalar field f on the 2dimensional differentiable manifold M sage: f.add_expr_by_continuation(c_uv, U.intersection(V)) sage: f.display() f: M > R on U: (x, y) > 1/(x^2 + y^2 + 1) on V: (u, v) > (u^2 + v^2)/(u^2 + v^2 + 1)
A scalar field can also be defined by some unspecified function of the coordinates:
sage: h = U.scalar_field(function('H')(x, y), name='h') ; h Scalar field h on the Open subset U of the 2dimensional differentiable manifold M sage: h.display() h: U > R (x, y) > H(x, y) on W: (u, v) > H(u/(u^2 + v^2), v/(u^2 + v^2))
We may use the argument
latex_name
to specify the LaTeX symbol denoting the scalar field if the latter is different fromname
:sage: latex(f) f sage: f = M.scalar_field({c_xy: 1/(1+x^2+y^2), c_uv: (u^2+v^2)/(1+u^2+v^2)}, ....: name='f', latex_name=r'\mathcal{F}') sage: latex(f) \mathcal{F}
The coordinate expression in a given chart is obtained via the method
expr()
, which returns a symbolic expression:sage: f.expr(c_uv) (u^2 + v^2)/(u^2 + v^2 + 1) sage: type(f.expr(c_uv)) <type 'sage.symbolic.expression.Expression'>
The method
coord_function()
returns instead a function of the chart coordinates, i.e. an instance ofChartFunction
:sage: f.coord_function(c_uv) (u^2 + v^2)/(u^2 + v^2 + 1) sage: type(f.coord_function(c_uv)) <class 'sage.manifolds.chart_func.ChartFunctionRing_with_category.element_class'> sage: f.coord_function(c_uv).display() (u, v) > (u^2 + v^2)/(u^2 + v^2 + 1)
The value returned by the method
expr()
is actually the coordinate expression of the chart function:sage: f.expr(c_uv) is f.coord_function(c_uv).expr() True
A constant scalar field is declared by setting the argument
chart
to'all'
:sage: c = M.scalar_field(2, chart='all', name='c') ; c Scalar field c on the 2dimensional differentiable manifold M sage: c.display() c: M > R on U: (x, y) > 2 on V: (u, v) > 2
A shortcut is to use the method
constant_scalar_field()
:sage: c == M.constant_scalar_field(2) True
The constant value can be some unspecified parameter:
sage: var('a') a sage: c = M.constant_scalar_field(a, name='c') ; c Scalar field c on the 2dimensional differentiable manifold M sage: c.display() c: M > R on U: (x, y) > a on V: (u, v) > a
A special case of constant field is the zero scalar field:
sage: zer = M.constant_scalar_field(0) ; zer Scalar field zero on the 2dimensional differentiable manifold M sage: zer.display() zero: M > R on U: (x, y) > 0 on V: (u, v) > 0
It can be obtained directly by means of the function
zero_scalar_field()
:sage: zer is M.zero_scalar_field() True
A third way is to get it as the zero element of the algebra \(C^k(M)\) of scalar fields on \(M\) (see below):
sage: zer is M.scalar_field_algebra().zero() True
By definition, a scalar field acts on the manifold’s points, sending them to elements of the manifold’s base field (real numbers in the present case):
sage: N = M.point((0,0), chart=c_uv) # the North pole sage: S = M.point((0,0), chart=c_xy) # the South pole sage: E = M.point((1,0), chart=c_xy) # a point at the equator sage: f(N) 0 sage: f(S) 1 sage: f(E) 1/2 sage: h(E) H(1, 0) sage: c(E) a sage: zer(E) 0
A scalar field can be compared to another scalar field:
sage: f == g False
…to a symbolic expression:
sage: f == x*y False sage: g == x*y True sage: c == a True
…to a number:
sage: f == 2 False sage: zer == 0 True
…to anything else:
sage: f == M False
Standard mathematical functions are implemented:
sage: sqrt(f) Scalar field sqrt(f) on the 2dimensional differentiable manifold M sage: sqrt(f).display() sqrt(f): M > R on U: (x, y) > 1/sqrt(x^2 + y^2 + 1) on V: (u, v) > sqrt(u^2 + v^2)/sqrt(u^2 + v^2 + 1)
sage: tan(f) Scalar field tan(f) on the 2dimensional differentiable manifold M sage: tan(f).display() tan(f): M > R on U: (x, y) > sin(1/(x^2 + y^2 + 1))/cos(1/(x^2 + y^2 + 1)) on V: (u, v) > sin((u^2 + v^2)/(u^2 + v^2 + 1))/cos((u^2 + v^2)/(u^2 + v^2 + 1))
Arithmetics of scalar fields
Scalar fields on \(M\) (resp. \(U\)) belong to the algebra \(C^k(M)\) (resp. \(C^k(U)\)):
sage: f.parent() Algebra of differentiable scalar fields on the 2dimensional differentiable manifold M sage: f.parent() is M.scalar_field_algebra() True sage: g.parent() Algebra of differentiable scalar fields on the Open subset U of the 2dimensional differentiable manifold M sage: g.parent() is U.scalar_field_algebra() True
Consequently, scalar fields can be added:
sage: s = f + c ; s Scalar field f+c on the 2dimensional differentiable manifold M sage: s.display() f+c: M > R on U: (x, y) > (a*x^2 + a*y^2 + a + 1)/(x^2 + y^2 + 1) on V: (u, v) > ((a + 1)*u^2 + (a + 1)*v^2 + a)/(u^2 + v^2 + 1)
and subtracted:
sage: s = f  c ; s Scalar field fc on the 2dimensional differentiable manifold M sage: s.display() fc: M > R on U: (x, y) > (a*x^2 + a*y^2 + a  1)/(x^2 + y^2 + 1) on V: (u, v) > ((a  1)*u^2 + (a  1)*v^2 + a)/(u^2 + v^2 + 1)
Some tests:
sage: f + zer == f True sage: f  f == zer True sage: f + (f) == zer True sage: (f+c)f == c True sage: (fc)+c == f True
We may add a number (interpreted as a constant scalar field) to a scalar field:
sage: s = f + 1 ; s Scalar field on the 2dimensional differentiable manifold M sage: s.display() M > R on U: (x, y) > (x^2 + y^2 + 2)/(x^2 + y^2 + 1) on V: (u, v) > (2*u^2 + 2*v^2 + 1)/(u^2 + v^2 + 1) sage: (f+1)1 == f True
The number can represented by a symbolic variable:
sage: s = a + f ; s Scalar field on the 2dimensional differentiable manifold M sage: s == c + f True
However if the symbolic variable is a chart coordinate, the addition is performed only on the chart domain:
sage: s = f + x; s Scalar field on the 2dimensional differentiable manifold M sage: s.display() M > R on U: (x, y) > (x^3 + x*y^2 + x + 1)/(x^2 + y^2 + 1) sage: s = f + u; s Scalar field on the 2dimensional differentiable manifold M sage: s.display() M > R on V: (u, v) > (u^3 + (u + 1)*v^2 + u^2 + u)/(u^2 + v^2 + 1)
The addition of two scalar fields with different domains is possible if the domain of one of them is a subset of the domain of the other; the domain of the result is then this subset:
sage: f.domain() 2dimensional differentiable manifold M sage: g.domain() Open subset U of the 2dimensional differentiable manifold M sage: s = f + g ; s Scalar field on the Open subset U of the 2dimensional differentiable manifold M sage: s.domain() Open subset U of the 2dimensional differentiable manifold M sage: s.display() U > R (x, y) > (x*y^3 + (x^3 + x)*y + 1)/(x^2 + y^2 + 1) on W: (u, v) > (u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6 + u*v^3 + (u^3 + u)*v)/(u^6 + v^6 + (3*u^2 + 1)*v^4 + u^4 + (3*u^4 + 2*u^2)*v^2)
The operation actually performed is \(f_U + g\):
sage: s == f.restrict(U) + g True
In Sage framework, the addition of \(f\) and \(g\) is permitted because there is a coercion of the parent of \(f\), namely \(C^k(M)\), to the parent of \(g\), namely \(C^k(U)\) (see
DiffScalarFieldAlgebra
):sage: CM = M.scalar_field_algebra() sage: CU = U.scalar_field_algebra() sage: CU.has_coerce_map_from(CM) True
The coercion map is nothing but the restriction to domain \(U\):
sage: CU.coerce(f) == f.restrict(U) True
Since the algebra \(C^k(M)\) is a vector space over \(\RR\), scalar fields can be multiplied by a number, either an explicit one:
sage: s = 2*f ; s Scalar field on the 2dimensional differentiable manifold M sage: s.display() M > R on U: (x, y) > 2/(x^2 + y^2 + 1) on V: (u, v) > 2*(u^2 + v^2)/(u^2 + v^2 + 1)
or a symbolic one:
sage: s = a*f ; s Scalar field on the 2dimensional differentiable manifold M sage: s.display() M > R on U: (x, y) > a/(x^2 + y^2 + 1) on V: (u, v) > (u^2 + v^2)*a/(u^2 + v^2 + 1)
However, if the symbolic variable is a chart coordinate, the multiplication is performed only in the corresponding chart:
sage: s = x*f; s Scalar field on the 2dimensional differentiable manifold M sage: s.display() M > R on U: (x, y) > x/(x^2 + y^2 + 1) sage: s = u*f; s Scalar field on the 2dimensional differentiable manifold M sage: s.display() M > R on V: (u, v) > (u^2 + v^2)*u/(u^2 + v^2 + 1)
Some tests:
sage: 0*f == 0 True sage: 0*f == zer True sage: 1*f == f True sage: (2)*f ==  f  f True
The ring multiplication of the algebras \(C^k(M)\) and \(C^k(U)\) is the pointwise multiplication of functions:
sage: s = f*f ; s Scalar field f*f on the 2dimensional differentiable manifold M sage: s.display() f*f: M > R on U: (x, y) > 1/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) on V: (u, v) > (u^4 + 2*u^2*v^2 + v^4)/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) sage: s = g*h ; s Scalar field g*h on the Open subset U of the 2dimensional differentiable manifold M sage: s.display() g*h: U > R (x, y) > x*y*H(x, y) on W: (u, v) > u*v*H(u/(u^2 + v^2), v/(u^2 + v^2))/(u^4 + 2*u^2*v^2 + v^4)
Thanks to the coercion \(C^k(M)\rightarrow C^k(U)\) mentionned above, it is possible to multiply a scalar field defined on \(M\) by a scalar field defined on \(U\), the result being a scalar field defined on \(U\):
sage: f.domain(), g.domain() (2dimensional differentiable manifold M, Open subset U of the 2dimensional differentiable manifold M) sage: s = f*g ; s Scalar field on the Open subset U of the 2dimensional differentiable manifold M sage: s.display() U > R (x, y) > x*y/(x^2 + y^2 + 1) on W: (u, v) > u*v/(u^4 + v^4 + (2*u^2 + 1)*v^2 + u^2) sage: s == f.restrict(U)*g True
Scalar fields can be divided (pointwise division):
sage: s = f/c ; s Scalar field f/c on the 2dimensional differentiable manifold M sage: s.display() f/c: M > R on U: (x, y) > 1/(a*x^2 + a*y^2 + a) on V: (u, v) > (u^2 + v^2)/(a*u^2 + a*v^2 + a) sage: s = g/h ; s Scalar field g/h on the Open subset U of the 2dimensional differentiable manifold M sage: s.display() g/h: U > R (x, y) > x*y/H(x, y) on W: (u, v) > u*v/((u^4 + 2*u^2*v^2 + v^4)*H(u/(u^2 + v^2), v/(u^2 + v^2))) sage: s = f/g ; s Scalar field on the Open subset U of the 2dimensional differentiable manifold M sage: s.display() U > R (x, y) > 1/(x*y^3 + (x^3 + x)*y) on W: (u, v) > (u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6)/(u*v^3 + (u^3 + u)*v) sage: s == f.restrict(U)/g True
For scalar fields defined on a single chart domain, we may perform some arithmetics with symbolic expressions involving the chart coordinates:
sage: s = g + x^2  y ; s Scalar field on the Open subset U of the 2dimensional differentiable manifold M sage: s.display() U > R (x, y) > x^2 + (x  1)*y on W: (u, v) > (v^3  u^2 + (u^2  u)*v)/(u^4 + 2*u^2*v^2 + v^4)
sage: s = g*x ; s Scalar field on the Open subset U of the 2dimensional differentiable manifold M sage: s.display() U > R (x, y) > x^2*y on W: (u, v) > u^2*v/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6)
sage: s = g/x ; s Scalar field on the Open subset U of the 2dimensional differentiable manifold M sage: s.display() U > R (x, y) > y on W: (u, v) > v/(u^2 + v^2) sage: s = x/g ; s Scalar field on the Open subset U of the 2dimensional differentiable manifold M sage: s.display() U > R (x, y) > 1/y on W: (u, v) > (u^2 + v^2)/v
The test suite is passed:
sage: TestSuite(f).run() sage: TestSuite(zer).run()

bracket
(other)¶ Return the SchoutenNijenhuis bracket of
self
, considered as a multivector field of degree 0, with a multivector field.See
bracket()
for details.INPUT:
other
– a multivector field of degree \(p\)
OUTPUT:
 if \(p=0\), a zero scalar field
 if \(p=1\), an instance of
DiffScalarField
representing the SchoutenNijenhuis bracket[self,other]
 if \(p\geq 2\), an instance of
MultivectorField
representing the SchoutenNijenhuis bracket[self,other]
EXAMPLES:
The SchoutenNijenhuis bracket of two scalar fields is identically zero:
sage: M = Manifold(2, 'M') sage: X.<x,y> = M.chart() sage: f = M.scalar_field({X: x+y^2}, name='f') sage: g = M.scalar_field({X: yx}, name='g') sage: s = f.bracket(g); s Scalar field zero on the 2dimensional differentiable manifold M sage: s.display() zero: M > R (x, y) > 0
while the SchoutenNijenhuis bracket of a scalar field \(f\) with a multivector field \(a\) is equal to minus the interior product of the differential of \(f\) with \(a\):
sage: a = M.multivector_field(2, name='a') sage: a[0,1] = x*y ; a.display() a = x*y d/dx/\d/dy sage: s = f.bracket(a); s Vector field i_df a on the 2dimensional differentiable manifold M sage: s.display() i_df a = 2*x*y^2 d/dx  x*y d/dy
See
bracket()
for other examples.

dalembertian
(metric=None)¶ Return the d’Alembertian of
self
with respect to a given Lorentzian metric.The d’Alembertian of a scalar field \(f\) with respect to a Lorentzian metric \(g\) is nothing but the Laplacian (see
laplacian()
) of \(f\) with respect to that metric:\[\Box f = g^{ij} \nabla_i \nabla_j f = \nabla_i \nabla^i f\]where \(\nabla\) is the LeviCivita connection of \(g\).
Note
If the metric \(g\) is not Lorentzian, the name d’Alembertian is not appropriate and one should use
laplacian()
instead.INPUT:
metric
– (default:None
) the Lorentzian metric \(g\) involved in the definition of the d’Alembertian; if none is provided, the domain ofself
is supposed to be endowed with a default Lorentzian metric (i.e. is supposed to be Lorentzian manifold, seePseudoRiemannianManifold
) and the latter is used to define the d’Alembertian
OUTPUT:
 instance of
DiffScalarField
representing the d’Alembertian ofself
EXAMPLES:
d’Alembertian of a scalar field in Minkowski spacetime:
sage: M = Manifold(4, 'M', structure='Lorentzian') sage: X.<t,x,y,z> = M.chart() sage: g = M.metric() sage: g[0,0], g[1,1], g[2,2], g[3,3] = 1, 1, 1, 1 sage: f = M.scalar_field(t + x^2 + t^2*y^3  x*z^4, name='f') sage: s = f.dalembertian(); s Scalar field Box(f) on the 4dimensional Lorentzian manifold M sage: s.display() Box(f): M > R (t, x, y, z) > 6*t^2*y  2*y^3  12*x*z^2 + 2
The function
dalembertian()
from theoperators
module can be used instead of the methoddalembertian()
:sage: from sage.manifolds.operators import dalembertian sage: dalembertian(f) == s True

degree
()¶ Return the degree of
self
, considered as a differential form or a multivector field, i.e. zero.This trivial method is provided for consistency with the exterior calculus scheme, cf. the methods
degree()
(differential forms) anddegree()
(multivector fields).OUTPUT:
 0
EXAMPLES:
sage: M = Manifold(2, 'M') sage: X.<x,y> = M.chart() sage: f = M.scalar_field({X: x+y^2}) sage: f.degree() 0

differential
()¶ Return the differential of
self
.OUTPUT:
 a
DiffForm
(or ofDiffFormParal
if the scalar field’s domain is parallelizable) representing the 1form that is the differential of the scalar field
EXAMPLES:
Differential of a scalar field on a 3dimensional differentiable manifold:
sage: M = Manifold(3, 'M') sage: c_xyz.<x,y,z> = M.chart() sage: f = M.scalar_field(cos(x)*z^3 + exp(y)*z^2, name='f') sage: df = f.differential() ; df 1form df on the 3dimensional differentiable manifold M sage: df.display() df = z^3*sin(x) dx + z^2*e^y dy + (3*z^2*cos(x) + 2*z*e^y) dz sage: latex(df) \mathrm{d}f sage: df.parent() Free module Omega^1(M) of 1forms on the 3dimensional differentiable manifold M
The result is cached, i.e. is not recomputed unless
f
is changed:sage: f.differential() is df True
Since the exterior derivative of a scalar field (considered a 0form) is nothing but its differential,
exterior_derivative()
is an alias ofdifferential()
:sage: df = f.exterior_derivative() ; df 1form df on the 3dimensional differentiable manifold M sage: df.display() df = z^3*sin(x) dx + z^2*e^y dy + (3*z^2*cos(x) + 2*z*e^y) dz sage: latex(df) \mathrm{d}f
One may also use the function
exterior_derivative()
or its aliasxder()
instead of the methodexterior_derivative()
:sage: from sage.manifolds.utilities import xder sage: xder(f) is f.exterior_derivative() True
Differential computed on a chart that is not the default one:
sage: c_uvw.<u,v,w> = M.chart() sage: g = M.scalar_field(u*v^2*w^3, c_uvw, name='g') sage: dg = g.differential() ; dg 1form dg on the 3dimensional differentiable manifold M sage: dg._components {Coordinate frame (M, (d/du,d/dv,d/dw)): 1index components w.r.t. Coordinate frame (M, (d/du,d/dv,d/dw))} sage: dg.comp(c_uvw.frame())[:, c_uvw] [v^2*w^3, 2*u*v*w^3, 3*u*v^2*w^2] sage: dg.display(c_uvw.frame(), c_uvw) dg = v^2*w^3 du + 2*u*v*w^3 dv + 3*u*v^2*w^2 dw
The exterior derivative is nilpotent:
sage: ddf = df.exterior_derivative() ; ddf 2form ddf on the 3dimensional differentiable manifold M sage: ddf == 0 True sage: ddf[:] # for the incredule [0 0 0] [0 0 0] [0 0 0] sage: ddg = dg.exterior_derivative() ; ddg 2form ddg on the 3dimensional differentiable manifold M sage: ddg == 0 True
 a

exterior_derivative
()¶ Return the differential of
self
.OUTPUT:
 a
DiffForm
(or ofDiffFormParal
if the scalar field’s domain is parallelizable) representing the 1form that is the differential of the scalar field
EXAMPLES:
Differential of a scalar field on a 3dimensional differentiable manifold:
sage: M = Manifold(3, 'M') sage: c_xyz.<x,y,z> = M.chart() sage: f = M.scalar_field(cos(x)*z^3 + exp(y)*z^2, name='f') sage: df = f.differential() ; df 1form df on the 3dimensional differentiable manifold M sage: df.display() df = z^3*sin(x) dx + z^2*e^y dy + (3*z^2*cos(x) + 2*z*e^y) dz sage: latex(df) \mathrm{d}f sage: df.parent() Free module Omega^1(M) of 1forms on the 3dimensional differentiable manifold M
The result is cached, i.e. is not recomputed unless
f
is changed:sage: f.differential() is df True
Since the exterior derivative of a scalar field (considered a 0form) is nothing but its differential,
exterior_derivative()
is an alias ofdifferential()
:sage: df = f.exterior_derivative() ; df 1form df on the 3dimensional differentiable manifold M sage: df.display() df = z^3*sin(x) dx + z^2*e^y dy + (3*z^2*cos(x) + 2*z*e^y) dz sage: latex(df) \mathrm{d}f
One may also use the function
exterior_derivative()
or its aliasxder()
instead of the methodexterior_derivative()
:sage: from sage.manifolds.utilities import xder sage: xder(f) is f.exterior_derivative() True
Differential computed on a chart that is not the default one:
sage: c_uvw.<u,v,w> = M.chart() sage: g = M.scalar_field(u*v^2*w^3, c_uvw, name='g') sage: dg = g.differential() ; dg 1form dg on the 3dimensional differentiable manifold M sage: dg._components {Coordinate frame (M, (d/du,d/dv,d/dw)): 1index components w.r.t. Coordinate frame (M, (d/du,d/dv,d/dw))} sage: dg.comp(c_uvw.frame())[:, c_uvw] [v^2*w^3, 2*u*v*w^3, 3*u*v^2*w^2] sage: dg.display(c_uvw.frame(), c_uvw) dg = v^2*w^3 du + 2*u*v*w^3 dv + 3*u*v^2*w^2 dw
The exterior derivative is nilpotent:
sage: ddf = df.exterior_derivative() ; ddf 2form ddf on the 3dimensional differentiable manifold M sage: ddf == 0 True sage: ddf[:] # for the incredule [0 0 0] [0 0 0] [0 0 0] sage: ddg = dg.exterior_derivative() ; ddg 2form ddg on the 3dimensional differentiable manifold M sage: ddg == 0 True
 a

gradient
(metric=None)¶ Return the gradient of
self
(with respect to a given metric).The gradient of a scalar field \(f\) with respect to a metric \(g\) is the vector field \(\mathrm{grad}\, f\) whose components in any coordinate frame are
\[(\mathrm{grad}\, f)^i = g^{ij} \frac{\partial F}{\partial x^j}\]where the \(x^j\)‘s are the coordinates with respect to which the frame is defined and \(F\) is the chart function representing \(f\) in these coordinates: \(f(p) = F(x^1(p),\ldots,x^n(p))\) for any point \(p\) in the chart domain. In other words, the gradient of \(f\) is the vector field that is the \(g\)dual of the differential of \(f\).
INPUT:
metric
– (default:None
) the pseudoRiemannian metric \(g\) involved in the definition of the gradient; if none is provided, the domain ofself
is supposed to be endowed with a default metric (i.e. is supposed to be pseudoRiemannian manifold, seePseudoRiemannianManifold
) and the latter is used to define the gradient
OUTPUT:
 instance of
VectorField
representing the gradient ofself
EXAMPLES:
Gradient of a scalar field in the Euclidean plane:
sage: M = Manifold(2, 'M', structure='Riemannian') sage: X.<x,y> = M.chart() sage: g = M.metric() sage: g[0,0], g[1,1] = 1, 1 sage: f = M.scalar_field(cos(x*y), name='f') sage: v = f.gradient(); v Vector field grad(f) on the 2dimensional Riemannian manifold M sage: v.display() grad(f) = y*sin(x*y) d/dx  x*sin(x*y) d/dy
The function
grad()
from theoperators
module can be used instead of the methodgradient()
:sage: from sage.manifolds.operators import grad sage: grad(f) == f.gradient() True
The gradient can be taken with respect to a metric tensor that is not the default one:
sage: h = M.lorentzian_metric('h') sage: h[0,0], h[1,1] = 1, 1/(1+x^2+y^2) sage: h.display() h = dx*dx + 1/(x^2 + y^2 + 1) dy*dy sage: v = f.gradient(h); v Vector field grad_h(f) on the 2dimensional Riemannian manifold M sage: v.display() grad_h(f) = y*sin(x*y) d/dx  (x^3 + x*y^2 + x)*sin(x*y) d/dy

hodge_dual
(metric)¶ Compute the Hodge dual of the scalar field with respect to some metric.
If \(M\) is the domain of the scalar field (denoted by \(f\)), \(n\) is the dimension of \(M\) and \(g\) is a pseudoRiemannian metric on \(M\), the Hodge dual of \(f\) w.r.t. \(g\) is the \(n\)form \(*f\) defined by
\[*f = f \epsilon,\]where \(\epsilon\) is the volume \(n\)form associated with \(g\) (see
volume_form()
).INPUT:
metric
– a pseudoRiemannian metric defined on the same manifold as the current scalar field; must be an instance ofPseudoRiemannianMetric
OUTPUT:
 the \(n\)form \(*f\)
EXAMPLES:
Hodge dual of a scalar field in the Euclidean space \(R^3\):
sage: M = Manifold(3, 'M', start_index=1) sage: X.<x,y,z> = M.chart() sage: g = M.metric('g') sage: g[1,1], g[2,2], g[3,3] = 1, 1, 1 sage: f = M.scalar_field(function('F')(x,y,z), name='f') sage: sf = f.hodge_dual(g) ; sf 3form *f on the 3dimensional differentiable manifold M sage: sf.display() *f = F(x, y, z) dx/\dy/\dz sage: ssf = sf.hodge_dual(g) ; ssf Scalar field **f on the 3dimensional differentiable manifold M sage: ssf.display() **f: M > R (x, y, z) > F(x, y, z) sage: ssf == f # must hold for a Riemannian metric True
Instead of calling the method
hodge_dual()
on the scalar field, one can invoke the methodhodge_star()
of the metric:sage: f.hodge_dual(g) == g.hodge_star(f) True

laplacian
(metric=None)¶ Return the Laplacian of
self
with respect to a given metric (LaplaceBeltrami operator).The Laplacian of a scalar field \(f\) with respect to a metric \(g\) is the scalar field
\[\Delta f = g^{ij} \nabla_i \nabla_j f = \nabla_i \nabla^i f\]where \(\nabla\) is the LeviCivita connection of \(g\). \(\Delta\) is also called the LaplaceBeltrami operator.
INPUT:
metric
– (default:None
) the pseudoRiemannian metric \(g\) involved in the definition of the Laplacian; if none is provided, the domain ofself
is supposed to be endowed with a default metric (i.e. is supposed to be pseudoRiemannian manifold, seePseudoRiemannianManifold
) and the latter is used to define the Laplacian
OUTPUT:
 instance of
DiffScalarField
representing the Laplacian ofself
EXAMPLES:
Laplacian of a scalar field on the Euclidean plane:
sage: M = Manifold(2, 'M', structure='Riemannian') sage: X.<x,y> = M.chart() sage: g = M.metric() sage: g[0,0], g[1,1] = 1, 1 sage: f = M.scalar_field(function('F')(x,y), name='f') sage: s = f.laplacian(); s Scalar field Delta(f) on the 2dimensional Riemannian manifold M sage: s.display() Delta(f): M > R (x, y) > d^2(F)/dx^2 + d^2(F)/dy^2
The function
laplacian()
from theoperators
module can be used instead of the methodlaplacian()
:sage: from sage.manifolds.operators import laplacian sage: laplacian(f) == s True
The Laplacian can be taken with respect to a metric tensor that is not the default one:
sage: h = M.lorentzian_metric('h') sage: h[0,0], h[1,1] = 1, 1/(1+x^2+y^2) sage: s = f.laplacian(h); s Scalar field Delta_h(f) on the 2dimensional Riemannian manifold M sage: s.display() Delta_h(f): M > R (x, y) > (y^4*d^2(F)/dy^2 + y^3*d(F)/dy + (2*(x^2 + 1)*d^2(F)/dy^2  d^2(F)/dx^2)*y^2 + (x^2 + 1)*y*d(F)/dy + x*d(F)/dx  (x^2 + 1)*d^2(F)/dx^2 + (x^4 + 2*x^2 + 1)*d^2(F)/dy^2)/(x^2 + y^2 + 1)
The Laplacian of \(f\) is equal to the divergence of the gradient of \(f\):
\[\Delta f = \mathrm{div}( \mathrm{grad}\, f )\]Let us check this formula:
sage: s == f.gradient(h).div(h) True

lie_der
(vector)¶ Compute the Lie derivative with respect to a vector field.
In the present case (scalar field), the Lie derivative is equal to the scalar field resulting from the action of the vector field on the scalar field.
INPUT:
vector
– vector field with respect to which the Lie derivative is to be taken
OUTPUT:
 the scalar field that is the Lie derivative of the scalar field with
respect to
vector
EXAMPLES:
Lie derivative on a 2dimensional manifold:
sage: M = Manifold(2, 'M') sage: c_xy.<x,y> = M.chart() sage: f = M.scalar_field(x^2*cos(y)) sage: v = M.vector_field(name='v') sage: v[:] = (y, x) sage: f.lie_derivative(v) Scalar field on the 2dimensional differentiable manifold M sage: f.lie_derivative(v).expr() x^3*sin(y)  2*x*y*cos(y)
The result is cached:
sage: f.lie_derivative(v) is f.lie_derivative(v) True
An alias is
lie_der
:sage: f.lie_der(v) is f.lie_derivative(v) True
Alternative expressions of the Lie derivative of a scalar field:
sage: f.lie_der(v) == v(f) # the vector acting on f True sage: f.lie_der(v) == f.differential()(v) # the differential of f acting on the vector True
A vanishing Lie derivative:
sage: f.set_expr(x^2 + y^2) sage: f.lie_der(v).display() M > R (x, y) > 0

lie_derivative
(vector)¶ Compute the Lie derivative with respect to a vector field.
In the present case (scalar field), the Lie derivative is equal to the scalar field resulting from the action of the vector field on the scalar field.
INPUT:
vector
– vector field with respect to which the Lie derivative is to be taken
OUTPUT:
 the scalar field that is the Lie derivative of the scalar field with
respect to
vector
EXAMPLES:
Lie derivative on a 2dimensional manifold:
sage: M = Manifold(2, 'M') sage: c_xy.<x,y> = M.chart() sage: f = M.scalar_field(x^2*cos(y)) sage: v = M.vector_field(name='v') sage: v[:] = (y, x) sage: f.lie_derivative(v) Scalar field on the 2dimensional differentiable manifold M sage: f.lie_derivative(v).expr() x^3*sin(y)  2*x*y*cos(y)
The result is cached:
sage: f.lie_derivative(v) is f.lie_derivative(v) True
An alias is
lie_der
:sage: f.lie_der(v) is f.lie_derivative(v) True
Alternative expressions of the Lie derivative of a scalar field:
sage: f.lie_der(v) == v(f) # the vector acting on f True sage: f.lie_der(v) == f.differential()(v) # the differential of f acting on the vector True
A vanishing Lie derivative:
sage: f.set_expr(x^2 + y^2) sage: f.lie_der(v).display() M > R (x, y) > 0

tensor_type
()¶ Return the tensor type of
self
, when the latter is considered as a tensor field on the manifold. This is always \((0, 0)\).OUTPUT:
 always \((0, 0)\)
EXAMPLES:
sage: M = Manifold(2, 'M') sage: c_xy.<x,y> = M.chart() sage: f = M.scalar_field(x+2*y) sage: f.tensor_type() (0, 0)

wedge
(other)¶ Return the exterior product of
self
, considered as a differential form of degree 0 or a multivector field of degree 0, withother
.See
wedge()
(exterior product of differential forms) orwedge()
(exterior product of multivector fields) for details.For a scalar field \(f\) and a \(p\)form (or \(p\)vector field) \(a\), the exterior product reduces to the standard product on the left by an element of the base ring of the module of \(p\)forms (or \(p\)vector fields): \(f\wedge a = f a\).
INPUT:
other
– a differential form or a multivector field \(a\)
OUTPUT:
 the product \(f a\), where \(f\) is
self
EXAMPLES:
sage: M = Manifold(2, 'M') sage: X.<x,y> = M.chart() sage: f = M.scalar_field({X: x+y^2}, name='f') sage: a = M.diff_form(2, name='a') sage: a[0,1] = x*y sage: s = f.wedge(a); s 2form on the 2dimensional differentiable manifold M sage: s.display() (x*y^3 + x^2*y) dx/\dy