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 (2013-2015): 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 eithera 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 2-sphere:
sage: M = Manifold(2, 'M') # the 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 f-c on the 2-dimensional 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)
Some tests:
sage: f + zer == f True sage: f - f == zer True sage: f + (-f) == zer True sage: (f+c)-f == c True sage: (f-c)+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 f+1 on the 2-dimensional differentiable manifold M sage: s.display() f+1: 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 2-dimensional 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 2-dimensional differentiable manifold M sage: s.display() M --> R on U: (x, y) |--> (x^3 + x*y^2 + x + 1)/(x^2 + y^2 + 1) on W: (u, v) |--> (u^4 + v^4 + u^3 + (2*u^2 + u)*v^2 + u)/(u^4 + v^4 + (2*u^2 + 1)*v^2 + u^2) sage: s = f + u; s Scalar field on the 2-dimensional differentiable manifold M sage: s.display() M --> R on W: (x, y) |--> (x^3 + (x + 1)*y^2 + x^2 + x)/(x^4 + y^4 + (2*x^2 + 1)*y^2 + x^2) 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() 2-dimensional differentiable manifold M sage: g.domain() Open subset U of the 2-dimensional differentiable manifold M sage: s = f + g ; s Scalar field f+g on the Open subset U of the 2-dimensional differentiable manifold M sage: s.domain() Open subset U of the 2-dimensional differentiable manifold M sage: s.display() f+g: 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 2-dimensional 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 2-dimensional 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 2-dimensional differentiable manifold M sage: s.display() M --> R on U: (x, y) |--> x/(x^2 + y^2 + 1) on W: (u, v) |--> u/(u^2 + v^2 + 1) sage: s = u*f; s Scalar field on the 2-dimensional differentiable manifold M sage: s.display() M --> R on W: (x, y) |--> x/(x^4 + y^4 + (2*x^2 + 1)*y^2 + x^2) 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 2-dimensional 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 2-dimensional 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)\) mentioned 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() (2-dimensional differentiable manifold M, Open subset U of the 2-dimensional differentiable manifold M) sage: s = f*g ; s Scalar field f*g on the Open subset U of the 2-dimensional differentiable manifold M sage: s.display() f*g: 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 2-dimensional 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 2-dimensional 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 f/g on the Open subset U of the 2-dimensional differentiable manifold M sage: s.display() f/g: 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 Schouten-Nijenhuis 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 Schouten-Nijenhuis bracket[self,other]
if \(p\geq 2\), an instance of
MultivectorField
representing the Schouten-Nijenhuis bracket[self,other]
EXAMPLES:
The Schouten-Nijenhuis 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: y-x}, name='g') sage: s = f.bracket(g); s Scalar field zero on the 2-dimensional differentiable manifold M sage: s.display() zero: M --> R (x, y) |--> 0
while the Schouten-Nijenhuis 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 2-dimensional 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 Levi-Civita 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 4-dimensional 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
-
derivative
()¶ Return the differential of
self
.OUTPUT:
a
DiffForm
(or ofDiffFormParal
if the scalar field’s domain is parallelizable) representing the 1-form that is the differential of the scalar field
EXAMPLES:
Differential of a scalar field on a 3-dimensional 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 1-form df on the 3-dimensional 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 1-forms on the 3-dimensional differentiable manifold M
The result is cached, i.e. is not recomputed unless
f
is changed:sage: f.differential() is df True
Instead of invoking the method
differential()
, one may apply the functiondiff
to the scalar field:sage: diff(f) is f.differential() True
Since the exterior derivative of a scalar field (considered a 0-form) is nothing but its differential,
exterior_derivative()
is an alias ofdifferential()
:sage: df = f.exterior_derivative() ; df 1-form df on the 3-dimensional 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
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 1-form dg on the 3-dimensional differentiable manifold M sage: dg._components {Coordinate frame (M, (d/du,d/dv,d/dw)): 1-index 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) 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 2-form ddf on the 3-dimensional 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 2-form ddg on the 3-dimensional differentiable manifold M sage: ddg == 0 True
-
differential
()¶ Return the differential of
self
.OUTPUT:
a
DiffForm
(or ofDiffFormParal
if the scalar field’s domain is parallelizable) representing the 1-form that is the differential of the scalar field
EXAMPLES:
Differential of a scalar field on a 3-dimensional 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 1-form df on the 3-dimensional 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 1-forms on the 3-dimensional differentiable manifold M
The result is cached, i.e. is not recomputed unless
f
is changed:sage: f.differential() is df True
Instead of invoking the method
differential()
, one may apply the functiondiff
to the scalar field:sage: diff(f) is f.differential() True
Since the exterior derivative of a scalar field (considered a 0-form) is nothing but its differential,
exterior_derivative()
is an alias ofdifferential()
:sage: df = f.exterior_derivative() ; df 1-form df on the 3-dimensional 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
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 1-form dg on the 3-dimensional differentiable manifold M sage: dg._components {Coordinate frame (M, (d/du,d/dv,d/dw)): 1-index 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) 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 2-form ddf on the 3-dimensional 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 2-form ddg on the 3-dimensional differentiable manifold M sage: ddg == 0 True
-
exterior_derivative
()¶ Return the differential of
self
.OUTPUT:
a
DiffForm
(or ofDiffFormParal
if the scalar field’s domain is parallelizable) representing the 1-form that is the differential of the scalar field
EXAMPLES:
Differential of a scalar field on a 3-dimensional 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 1-form df on the 3-dimensional 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 1-forms on the 3-dimensional differentiable manifold M
The result is cached, i.e. is not recomputed unless
f
is changed:sage: f.differential() is df True
Instead of invoking the method
differential()
, one may apply the functiondiff
to the scalar field:sage: diff(f) is f.differential() True
Since the exterior derivative of a scalar field (considered a 0-form) is nothing but its differential,
exterior_derivative()
is an alias ofdifferential()
:sage: df = f.exterior_derivative() ; df 1-form df on the 3-dimensional 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
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 1-form dg on the 3-dimensional differentiable manifold M sage: dg._components {Coordinate frame (M, (d/du,d/dv,d/dw)): 1-index 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) 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 2-form ddf on the 3-dimensional 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 2-form ddg on the 3-dimensional differentiable manifold M sage: ddg == 0 True
-
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 pseudo-Riemannian 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 pseudo-Riemannian 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.<x,y> = EuclideanSpace() sage: f = M.scalar_field(cos(x*y), name='f') sage: v = f.gradient(); v Vector field grad(f) on the Euclidean plane E^2 sage: v.display() grad(f) = -y*sin(x*y) e_x - x*sin(x*y) e_y sage: v[:] [-y*sin(x*y), -x*sin(x*y)]
Gradient in polar coordinates:
sage: M.<r,phi> = EuclideanSpace(coordinates='polar') sage: f = M.scalar_field(r*cos(phi), name='f') sage: f.gradient().display() grad(f) = cos(phi) e_r - sin(phi) e_phi sage: f.gradient()[:] [cos(phi), -sin(phi)]
Note that
(e_r, e_phi)
is the orthonormal vector frame associated with polar coordinates (seepolar_frame()
); the gradient expressed in the coordinate frame is:sage: f.gradient().display(M.polar_coordinates().frame()) grad(f) = cos(phi) d/dr - sin(phi)/r d/dphi
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[1,1], h[2,2] = -1, 1/(1+r^2) sage: h.display(M.polar_coordinates().frame()) h = -dr*dr + r^2/(r^2 + 1) dphi*dphi sage: v = f.gradient(h); v Vector field grad_h(f) on the Euclidean plane E^2 sage: v.display() grad_h(f) = -cos(phi) e_r + (-r^2*sin(phi) - sin(phi)) e_phi
-
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 pseudo-Riemannian 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 pseudo-Riemannian 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 3-form *f on the 3-dimensional 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 3-dimensional 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 (Laplace-Beltrami 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 Levi-Civita connection of \(g\). \(\Delta\) is also called the Laplace-Beltrami operator.
INPUT:
metric
– (default:None
) the pseudo-Riemannian 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 pseudo-Riemannian 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.<x,y> = EuclideanSpace() sage: f = M.scalar_field(function('F')(x,y), name='f') sage: s = f.laplacian(); s Scalar field Delta(f) on the Euclidean plane E^2 sage: s.display() Delta(f): E^2 --> 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[1,1], h[2,2] = -1, 1/(1+x^2+y^2) sage: s = f.laplacian(h); s Scalar field Delta_h(f) on the Euclidean plane E^2 sage: s.display() Delta_h(f): E^2 --> 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-dimensional 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 2-form f*a on the 2-dimensional differentiable manifold M sage: s.display() f*a = (x*y^3 + x^2*y) dx/\dy