Pseudo-Riemannian Metrics and Degenerate Metrics¶
The class PseudoRiemannianMetric
implements pseudo-Riemannian metrics
on differentiable manifolds over \(\RR\). The derived class
PseudoRiemannianMetricParal
is devoted to metrics with values on a
parallelizable manifold.
The class DegenerateMetric
implements degenerate (or null or lightlike)
metrics on differentiable manifolds over \(\RR\). The derived class
DegenerateMetricParal
is devoted to metrics with values on a
parallelizable manifold.
AUTHORS:
Eric Gourgoulhon, Michal Bejger (2013-2015) : initial version
Pablo Angulo (2016) : Schouten, Cotton and Cotton-York tensors
Florentin Jaffredo (2018) : series expansion for the inverse metric
Hans Fotsing Tetsing (2019) : degenerate metrics
REFERENCES:
-
class
sage.manifolds.differentiable.metric.
DegenerateMetric
(vector_field_module, name, signature=None, latex_name=None)¶ Bases:
sage.manifolds.differentiable.tensorfield.TensorField
Degenerate (or null or lightlike) metric with values on an open subset of a differentiable manifold.
An instance of this class is a field of degenerate symmetric bilinear forms (metric field) along a differentiable manifold \(U\) with values on a differentiable manifold \(M\) over \(\RR\), via a differentiable mapping \(\Phi: U \rightarrow M\). The standard case of a degenerate metric field on a 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\)).
A degenerate metric \(g\) is a field on \(U\), such that at each point \(p\in U\), \(g(p)\) is a bilinear map of the type:
\[g(p):\ T_q M\times T_q M \longrightarrow \RR\]where \(T_q M\) stands for the tangent space to the manifold \(M\) at the point \(q=\Phi(p)\), such that \(g(p)\) is symmetric: \(\forall (u,v)\in T_q M\times T_q M, \ g(p)(v,u) = g(p)(u,v)\) and degenerate: \(\exists v\in T_q M;\ \ g(p)(u,v) = 0\ \ \forall u\in T_qM\).
Note
If \(M\) is parallelizable, the class
DegenerateMetricParal
should be used instead.INPUT:
vector_field_module
– module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(\Phi(U)\subset M\)name
– name given to the metricsignature
– (default:None
) signature \(S\) of the metric as a tuple: \(S = (n_+, n_-, n_0)\), where \(n_+\) (resp. \(n_-\), resp. \(n_0\)) is the number of positive terms (resp. negative terms, resp. zero tems) in any diagonal writing of the metric components; ifsignature
is not provided, \(S\) is set to \((ndim-1, 0, 1)\), being \(ndim\) the manifold’s dimensionlatex_name
– (default:None
) LaTeX symbol to denote the metric; ifNone
, it is formed fromname
EXAMPLES:
Lightlike cone:
sage: M = Manifold(3, 'M'); X.<x,y,z> = M.chart() sage: g = M.metric('g', signature=(2,0,1)); g degenerate metric g on the 3-dimensional differentiable manifold M sage: det(g) Scalar field zero on the 3-dimensional differentiable manifold M sage: g.parent() Free module T^(0,2)(M) of type-(0,2) tensors fields on the 3-dimensional differentiable manifold M sage: g[0,0], g[0,1], g[0,2] = (y^2 + z^2)/(x^2 + y^2 + z^2), \ ....: - x*y/(x^2 + y^2 + z^2), - x*z/(x^2 + y^2 + z^2) sage: g[1,1], g[1,2], g[2,2] = (x^2 + z^2)/(x^2 + y^2 + z^2), \ ....: - y*z/(x^2 + y^2 + z^2), (x^2 + y^2)/(x^2 + y^2 + z^2) sage: g.disp() g = (y^2 + z^2)/(x^2 + y^2 + z^2) dx*dx - x*y/(x^2 + y^2 + z^2) dx*dy - x*z/(x^2 + y^2 + z^2) dx*dz - x*y/(x^2 + y^2 + z^2) dy*dx + (x^2 + z^2)/(x^2 + y^2 + z^2) dy*dy - y*z/(x^2 + y^2 + z^2) dy*dz - x*z/(x^2 + y^2 + z^2) dz*dx - y*z/(x^2 + y^2 + z^2) dz*dy + (x^2 + y^2)/(x^2 + y^2 + z^2) dz*dz
The position vector is a lightlike vector field:
sage: v = M.vector_field() sage: v[0], v[1], v[2] = x , y, z sage: g(v, v).disp() M --> R (x, y, z) |--> 0
-
det
()¶ Determinant of a degenerate metric is always ‘0’
EXAMPLES:
sage: S = Manifold(2, 'S') sage: g = S.metric('g', signature=([0,1,1])) sage: g.determinant() Scalar field zero on the 2-dimensional differentiable manifold S
-
determinant
()¶ Determinant of a degenerate metric is always ‘0’
EXAMPLES:
sage: S = Manifold(2, 'S') sage: g = S.metric('g', signature=([0,1,1])) sage: g.determinant() Scalar field zero on the 2-dimensional differentiable manifold S
-
restrict
(subdomain, dest_map=None)¶ Return the restriction of the metric to some subdomain.
If the restriction has not been defined yet, it is constructed here.
INPUT:
subdomain
– open subset \(U\) of the metric’s domain (must be an instance ofDifferentiableManifold
)dest_map
– (default:None
) destination map \(\Phi:\ U \rightarrow V\), where \(V\) is a subdomain ofself._codomain
(type:DiffMap
) If None, the restriction ofself._vmodule._dest_map
to \(U\) is used.
OUTPUT:
instance of
DegenerateMetric
representing the restriction.
EXAMPLES:
sage: M = Manifold(5, 'M') sage: g = M.metric('g', signature=(3,1,1)) sage: U = M.open_subset('U') sage: g.restrict(U) degenerate metric g on the Open subset U of the 5-dimensional differentiable manifold M sage: g.restrict(U).signature() (3, 1, 1)
See the top documentation of
DegenerateMetric
for more examples.
-
set
(symbiform)¶ Defines the metric from a field of symmetric bilinear forms
INPUT:
symbiform
– instance ofTensorField
representing a field of symmetric bilinear forms
EXAMPLES:
Metric defined from a field of symmetric bilinear forms on a non-parallelizable 2-dimensional manifold:
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_uv.<u,v> = V.chart() sage: xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W', ....: restrictions1= x>0, restrictions2= u+v>0) sage: uv_to_xy = xy_to_uv.inverse() sage: W = U.intersection(V) sage: eU = c_xy.frame() ; eV = c_uv.frame() sage: h = M.sym_bilin_form_field(name='h') sage: h[eU,0,0], h[eU,0,1], h[eU,1,1] = 1+x, x*y, 1-y sage: h.add_comp_by_continuation(eV, W, c_uv) sage: h.display(eU) h = (x + 1) dx*dx + x*y dx*dy + x*y dy*dx + (-y + 1) dy*dy sage: h.display(eV) h = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du*du + 1/4*u du*dv + 1/4*u dv*du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv*dv sage: g = M.metric('g') sage: g.set(h) sage: g.display(eU) g = (x + 1) dx*dx + x*y dx*dy + x*y dy*dx + (-y + 1) dy*dy sage: g.display(eV) g = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du*du + 1/4*u du*dv + 1/4*u dv*du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv*dv
-
signature
()¶ Signature of the metric.
OUTPUT:
signature of a degenerate metric is defined as the tuple \((n_+,n_-,n_0)\), where \(n_+\) (resp. \(n_-\), resp. \(n_0\)) is the number of positive terms (resp. negative terms, resp. zero terms) eigenvalues
EXAMPLES:
Signatures on a 3-dimensional manifold:
sage: M = Manifold(3, 'M') sage: g = M.metric('g', signature=(1,1,1)) sage: g.signature() (1, 1, 1) sage: M = Manifold(3, 'M', structure='degenerate_metric') sage: g = M.metric() sage: g.signature() (0, 2, 1)
-
class
sage.manifolds.differentiable.metric.
DegenerateMetricParal
(vector_field_module, name, signature=None, latex_name=None)¶ Bases:
sage.manifolds.differentiable.metric.DegenerateMetric
,sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal
Degenerate (or null or lightlike) metric with values on an open subset of a differentiable manifold.
An instance of this class is a field of degenerate symmetric bilinear forms (metric field) along a differentiable manifold \(U\) with values on a differentiable manifold \(M\) over \(\RR\), via a differentiable mapping \(\Phi: U \rightarrow M\). The standard case of a degenerate metric field on a 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\)).
A degenerate metric \(g\) is a field on \(U\), such that at each point \(p\in U\), \(g(p)\) is a bilinear map of the type:
\[g(p):\ T_q M\times T_q M \longrightarrow \RR\]where \(T_q M\) stands for the tangent space to the manifold \(M\) at the point \(q=\Phi(p)\), such that \(g(p)\) is symmetric: \(\forall (u,v)\in T_q M\times T_q M, \ g(p)(v,u) = g(p)(u,v)\) and degenerate: \(\exists v\in T_q M;\ \ g(p)(u,v) = 0\ \ \forall u\in T_qM\).
Note
If \(M\) is not parallelizable, the class
DegenerateMetric
should be used instead.INPUT:
vector_field_module
– module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(\Phi(U)\subset M\)name
– name given to the metricsignature
– (default:None
) signature \(S\) of the metric as a tuple: \(S = (n_+, n_-, n_0)\), where \(n_+\) (resp. \(n_-\), resp. \(n_0\)) is the number of positive terms (resp. negative terms, resp. zero tems) in any diagonal writing of the metric components; ifsignature
is not provided, \(S\) is set to \((ndim-1, 0, 1)\), being \(ndim\) the manifold’s dimensionlatex_name
– (default:None
) LaTeX symbol to denote the metric; ifNone
, it is formed fromname
EXAMPLES:
Lightlike cone:
sage: M = Manifold(3, 'M'); X.<x,y,z> = M.chart() sage: g = M.metric('g', signature=(2,0,1)); g degenerate metric g on the 3-dimensional differentiable manifold M sage: det(g) Scalar field zero on the 3-dimensional differentiable manifold M sage: g.parent() Free module T^(0,2)(M) of type-(0,2) tensors fields on the 3-dimensional differentiable manifold M sage: g[0,0], g[0,1], g[0,2] = (y^2 + z^2)/(x^2 + y^2 + z^2), \ ....: - x*y/(x^2 + y^2 + z^2), - x*z/(x^2 + y^2 + z^2) sage: g[1,1], g[1,2], g[2,2] = (x^2 + z^2)/(x^2 + y^2 + z^2), \ ....: - y*z/(x^2 + y^2 + z^2), (x^2 + y^2)/(x^2 + y^2 + z^2) sage: g.disp() g = (y^2 + z^2)/(x^2 + y^2 + z^2) dx*dx - x*y/(x^2 + y^2 + z^2) dx*dy - x*z/(x^2 + y^2 + z^2) dx*dz - x*y/(x^2 + y^2 + z^2) dy*dx + (x^2 + z^2)/(x^2 + y^2 + z^2) dy*dy - y*z/(x^2 + y^2 + z^2) dy*dz - x*z/(x^2 + y^2 + z^2) dz*dx - y*z/(x^2 + y^2 + z^2) dz*dy + (x^2 + y^2)/(x^2 + y^2 + z^2) dz*dz
The position vector is a lightlike vector field:
sage: v = M.vector_field() sage: v[0], v[1], v[2] = x , y, z sage: g(v, v).disp() M --> R (x, y, z) |--> 0
-
restrict
(subdomain, dest_map=None)¶ Return the restriction of the metric to some subdomain.
If the restriction has not been defined yet, it is constructed here.
INPUT:
subdomain
– open subset \(U\) of the metric’s domain (must be an instance ofDifferentiableManifold
)dest_map
– (default:None
) destination map \(\Phi:\ U \rightarrow V\), where \(V\) is a subdomain ofself._codomain
(type:DiffMap
) If None, the restriction ofself._vmodule._dest_map
to \(U\) is used.
OUTPUT:
instance of
DegenerateMetric
representing the restriction.
EXAMPLES:
sage: M = Manifold(5, 'M') sage: g = M.metric('g', signature=(3,1,1)) sage: U = M.open_subset('U') sage: g.restrict(U) degenerate metric g on the Open subset U of the 5-dimensional differentiable manifold M sage: g.restrict(U).signature() (3, 1, 1)
See the top documentation of
DegenerateMetric
for more examples.
-
set
(symbiform)¶ Defines the metric from a field of symmetric bilinear forms
INPUT:
symbiform
– instance ofTensorField
representing a field of symmetric bilinear forms
EXAMPLES:
Metric defined from a field of symmetric bilinear forms on a parallelizable 3-dimensional manifold:
sage: M = Manifold(3, 'M', start_index=1); sage: X.<x,y,z> = M.chart() sage: dx, dy = X.coframe()[1], X.coframe()[2] sage: b = dx*dx + dy*dy sage: g = M.metric('g', signature=(1,1,1)); g degenerate metric g on the 3-dimensional differentiable manifold M sage: g.set(b) sage: g.display() g = dx*dx + dy*dy
-
class
sage.manifolds.differentiable.metric.
PseudoRiemannianMetric
(vector_field_module, name, signature=None, latex_name=None)¶ Bases:
sage.manifolds.differentiable.tensorfield.TensorField
Pseudo-Riemannian metric with values on an open subset of a differentiable manifold.
An instance of this class is a field of nondegenerate symmetric bilinear forms (metric field) along a differentiable manifold \(U\) with values on a differentiable manifold \(M\) over \(\RR\), via a differentiable mapping \(\Phi: U \rightarrow M\). The standard case of a metric field on a 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\)).
A metric \(g\) is a field on \(U\), such that at each point \(p\in U\), \(g(p)\) is a bilinear map of the type:
\[g(p):\ T_q M\times T_q M \longrightarrow \RR\]where \(T_q M\) stands for the tangent space to the manifold \(M\) at the point \(q=\Phi(p)\), such that \(g(p)\) is symmetric: \(\forall (u,v)\in T_q M\times T_q M, \ g(p)(v,u) = g(p)(u,v)\) and nondegenerate: \((\forall v\in T_q M,\ \ g(p)(u,v) = 0) \Longrightarrow u=0\).
Note
If \(M\) is parallelizable, the class
PseudoRiemannianMetricParal
should be used instead.INPUT:
vector_field_module
– module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(\Phi(U)\subset M\)name
– name given to the metricsignature
– (default:None
) signature \(S\) of the metric as a single integer: \(S = n_+ - n_-\), where \(n_+\) (resp. \(n_-\)) is the number of positive terms (resp. number of negative terms) in any diagonal writing of the metric components; ifsignature
isNone
, \(S\) is set to the dimension of manifold \(M\) (Riemannian signature)latex_name
– (default:None
) LaTeX symbol to denote the metric; ifNone
, it is formed fromname
EXAMPLES:
Let us construct the standard metric on the sphere \(S^2\), described in terms of stereographic coordinates, from the North pole (open subset \(U\)) and from the South pole (open subset \(V\)):
sage: M = Manifold(2, 'S^2', start_index=1) sage: U = M.open_subset('U') ; V = M.open_subset('V') sage: M.declare_union(U,V) # S^2 is the union of U and V sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart() # stereographic coord 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: eU = c_xy.frame() ; eV = c_uv.frame() sage: g = M.metric('g') ; g Riemannian metric g on the 2-dimensional differentiable manifold S^2
The metric is considered as a tensor field of type (0,2) on \(S^2\):
sage: g.parent() Module T^(0,2)(S^2) of type-(0,2) tensors fields on the 2-dimensional differentiable manifold S^2
We define \(g\) by its components on domain \(U\):
sage: g[eU,1,1], g[eU,2,2] = 4/(1+x^2+y^2)^2, 4/(1+x^2+y^2)^2 sage: g.display(eU) g = 4/(x^2 + y^2 + 1)^2 dx*dx + 4/(x^2 + y^2 + 1)^2 dy*dy
A matrix view of the components:
sage: g[eU,:] [4/(x^2 + y^2 + 1)^2 0] [ 0 4/(x^2 + y^2 + 1)^2]
The components of \(g\) on domain \(V\) expressed in terms of coordinates \((u,v)\) are obtained by applying (i) the tensor transformation law on \(W = U\cap V\) and (ii) some analytical continuation:
sage: W = U.intersection(V) sage: g.add_comp_by_continuation(eV, W, chart=c_uv) sage: g.apply_map(factor, frame=eV, keep_other_components=True) # for a nicer display sage: g.display(eV) g = 4/(u^2 + v^2 + 1)^2 du*du + 4/(u^2 + v^2 + 1)^2 dv*dv
At this stage, the metric is fully defined on the whole sphere. Its restriction to some subdomain is itself a metric (by default, it bears the same symbol):
sage: g.restrict(U) Riemannian metric g on the Open subset U of the 2-dimensional differentiable manifold S^2 sage: g.restrict(U).parent() Free module T^(0,2)(U) of type-(0,2) tensors fields on the Open subset U of the 2-dimensional differentiable manifold S^2
The parent of \(g|_U\) is a free module because is \(U\) is a parallelizable domain, contrary to \(S^2\). Actually, \(g\) and \(g|_U\) have different Python type:
sage: type(g) <class 'sage.manifolds.differentiable.metric.PseudoRiemannianMetric'> sage: type(g.restrict(U)) <class 'sage.manifolds.differentiable.metric.PseudoRiemannianMetricParal'>
As a field of bilinear forms, the metric acts on pairs of vector fields, yielding a scalar field:
sage: a = M.vector_field({eU: [x, 2+y]}, name='a') sage: a.add_comp_by_continuation(eV, W, chart=c_uv) sage: b = M.vector_field({eU: [-y, x]}, name='b') sage: b.add_comp_by_continuation(eV, W, chart=c_uv) sage: s = g(a,b) ; s Scalar field g(a,b) on the 2-dimensional differentiable manifold S^2 sage: s.display() g(a,b): S^2 --> R on U: (x, y) |--> 8*x/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) on V: (u, v) |--> 8*(u^3 + u*v^2)/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1)
The inverse metric is:
sage: ginv = g.inverse() ; ginv Tensor field inv_g of type (2,0) on the 2-dimensional differentiable manifold S^2 sage: ginv.parent() Module T^(2,0)(S^2) of type-(2,0) tensors fields on the 2-dimensional differentiable manifold S^2 sage: latex(ginv) g^{-1} sage: ginv.display(eU) inv_g = (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) d/dx*d/dx + (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) d/dy*d/dy sage: ginv.display(eV) inv_g = (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) d/du*d/du + (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) d/dv*d/dv
We have:
sage: ginv.restrict(U) is g.restrict(U).inverse() True sage: ginv.restrict(V) is g.restrict(V).inverse() True sage: ginv.restrict(W) is g.restrict(W).inverse() True
To get the volume form (Levi-Civita tensor) associated with \(g\), we have first to define an orientation on \(S^2\). The standard orientation is that in which
eV
is right-handed; indeed, once supplemented by the outward unit normal,eV
give birth to a right-handed frame with respect to the standard orientation of the ambient Euclidean space \(E^3\). With such an orientation,eU
is then left-handed and in order to define an orientation on the whole of \(S^2\), we introduce a vector frame on \(U\) by swappingeU
’s vectors:sage: f = U.vector_frame('f', (eU[2], eU[1])) sage: M.set_orientation([eV, f])
We have then, factorizing the components for a nicer display:
sage: eps = g.volume_form() ; eps 2-form eps_g on the 2-dimensional differentiable manifold S^2 sage: eps.apply_map(factor, frame=eU, keep_other_components=True) sage: eps.apply_map(factor, frame=eV, keep_other_components=True) sage: eps.display(eU) eps_g = -4/(x^2 + y^2 + 1)^2 dx/\dy sage: eps.display(eV) eps_g = 4/(u^2 + v^2 + 1)^2 du/\dv
The unique non-trivial component of the volume form is, up to a sign depending of the chosen orientation, nothing but the square root of the determinant of \(g\) in the corresponding frame:
sage: eps[[eU,1,2]] == -g.sqrt_abs_det(eU) True sage: eps[[eV,1,2]] == g.sqrt_abs_det(eV) True
The Levi-Civita connection associated with the metric \(g\):
sage: nabla = g.connection() ; nabla Levi-Civita connection nabla_g associated with the Riemannian metric g on the 2-dimensional differentiable manifold S^2 sage: latex(nabla) \nabla_{g}
The Christoffel symbols \(\Gamma^i_{\ \, jk}\) associated with some coordinates:
sage: g.christoffel_symbols(c_xy) 3-indices components w.r.t. Coordinate frame (U, (d/dx,d/dy)), with symmetry on the index positions (1, 2) sage: g.christoffel_symbols(c_xy)[:] [[[-2*x/(x^2 + y^2 + 1), -2*y/(x^2 + y^2 + 1)], [-2*y/(x^2 + y^2 + 1), 2*x/(x^2 + y^2 + 1)]], [[2*y/(x^2 + y^2 + 1), -2*x/(x^2 + y^2 + 1)], [-2*x/(x^2 + y^2 + 1), -2*y/(x^2 + y^2 + 1)]]] sage: g.christoffel_symbols(c_uv)[:] [[[-2*u/(u^2 + v^2 + 1), -2*v/(u^2 + v^2 + 1)], [-2*v/(u^2 + v^2 + 1), 2*u/(u^2 + v^2 + 1)]], [[2*v/(u^2 + v^2 + 1), -2*u/(u^2 + v^2 + 1)], [-2*u/(u^2 + v^2 + 1), -2*v/(u^2 + v^2 + 1)]]]
The Christoffel symbols are nothing but the connection coefficients w.r.t. the coordinate frame:
sage: g.christoffel_symbols(c_xy) is nabla.coef(c_xy.frame()) True sage: g.christoffel_symbols(c_uv) is nabla.coef(c_uv.frame()) True
Test that \(\nabla\) is the connection compatible with \(g\):
sage: t = nabla(g) ; t Tensor field nabla_g(g) of type (0,3) on the 2-dimensional differentiable manifold S^2 sage: t.display(eU) nabla_g(g) = 0 sage: t.display(eV) nabla_g(g) = 0 sage: t == 0 True
The Riemann curvature tensor of \(g\):
sage: riem = g.riemann() ; riem Tensor field Riem(g) of type (1,3) on the 2-dimensional differentiable manifold S^2 sage: riem.display(eU) Riem(g) = 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) d/dx*dy*dx*dy - 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) d/dx*dy*dy*dx - 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) d/dy*dx*dx*dy + 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) d/dy*dx*dy*dx sage: riem.display(eV) Riem(g) = 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) d/du*dv*du*dv - 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) d/du*dv*dv*du - 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) d/dv*du*du*dv + 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) d/dv*du*dv*du
The Ricci tensor of \(g\):
sage: ric = g.ricci() ; ric Field of symmetric bilinear forms Ric(g) on the 2-dimensional differentiable manifold S^2 sage: ric.display(eU) Ric(g) = 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) dx*dx + 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) dy*dy sage: ric.display(eV) Ric(g) = 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) du*du + 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) dv*dv sage: ric == g True
The Ricci scalar of \(g\):
sage: r = g.ricci_scalar() ; r Scalar field r(g) on the 2-dimensional differentiable manifold S^2 sage: r.display() r(g): S^2 --> R on U: (x, y) |--> 2 on V: (u, v) |--> 2
In dimension 2, the Riemann tensor can be expressed entirely in terms of the Ricci scalar \(r\):
\[R^i_{\ \, jlk} = \frac{r}{2} \left( \delta^i_{\ \, k} g_{jl} - \delta^i_{\ \, l} g_{jk} \right)\]This formula can be checked here, with the r.h.s. rewritten as \(-r g_{j[k} \delta^i_{\ \, l]}\):
sage: delta = M.tangent_identity_field() sage: riem == - r*(g*delta).antisymmetrize(2,3) True
-
christoffel_symbols
(chart=None)¶ Christoffel symbols of
self
with respect to a chart.INPUT:
chart
– (default:None
) chart with respect to which the Christoffel symbols are required; if none is provided, the default chart of the metric’s domain is assumed.
OUTPUT:
the set of Christoffel symbols in the given chart, as an instance of
CompWithSym
EXAMPLES:
Christoffel symbols of the flat metric on \(\RR^3\) with respect to spherical coordinates:
sage: M = Manifold(3, 'R3', r'\RR^3', start_index=1) sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0) sage: X.<r,th,ph> = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi') sage: g = U.metric('g') sage: g[1,1], g[2,2], g[3,3] = 1, r^2, r^2*sin(th)^2 sage: g.display() # the standard flat metric expressed in spherical coordinates g = dr*dr + r^2 dth*dth + r^2*sin(th)^2 dph*dph sage: Gam = g.christoffel_symbols() ; Gam 3-indices components w.r.t. Coordinate frame (U, (d/dr,d/dth,d/dph)), with symmetry on the index positions (1, 2) sage: type(Gam) <class 'sage.tensor.modules.comp.CompWithSym'> sage: Gam[:] [[[0, 0, 0], [0, -r, 0], [0, 0, -r*sin(th)^2]], [[0, 1/r, 0], [1/r, 0, 0], [0, 0, -cos(th)*sin(th)]], [[0, 0, 1/r], [0, 0, cos(th)/sin(th)], [1/r, cos(th)/sin(th), 0]]] sage: Gam[1,2,2] -r sage: Gam[2,1,2] 1/r sage: Gam[3,1,3] 1/r sage: Gam[3,2,3] cos(th)/sin(th) sage: Gam[2,3,3] -cos(th)*sin(th)
Note that a better display of the Christoffel symbols is provided by the method
christoffel_symbols_display()
:sage: g.christoffel_symbols_display() Gam^r_th,th = -r Gam^r_ph,ph = -r*sin(th)^2 Gam^th_r,th = 1/r Gam^th_ph,ph = -cos(th)*sin(th) Gam^ph_r,ph = 1/r Gam^ph_th,ph = cos(th)/sin(th)
-
christoffel_symbols_display
(chart=None, symbol=None, latex_symbol=None, index_labels=None, index_latex_labels=None, coordinate_labels=True, only_nonzero=True, only_nonredundant=True)¶ Display the Christoffel symbols w.r.t. to a given chart, one per line.
The output is either text-formatted (console mode) or LaTeX-formatted (notebook mode).
INPUT:
chart
– (default:None
) chart with respect to which the Christoffel symbols are defined; if none is provided, the default chart of the metric’s domain is assumed.symbol
– (default:None
) string specifying the symbol of the connection coefficients; ifNone
, ‘Gam’ is usedlatex_symbol
– (default:None
) string specifying the LaTeX symbol for the components; ifNone
, ‘\Gamma’ is usedindex_labels
– (default:None
) list of strings representing the labels of each index; ifNone
, coordinate symbols are used except ifcoordinate_symbols
is set toFalse
, in which case integer labels are usedindex_latex_labels
– (default:None
) list of strings representing the LaTeX labels of each index; ifNone
, coordinate LaTeX symbols are used, except ifcoordinate_symbols
is set toFalse
, in which case integer labels are usedcoordinate_labels
– (default:True
) boolean; ifTrue
, coordinate symbols are used by default (instead of integers)only_nonzero
– (default:True
) boolean; ifTrue
, only nonzero connection coefficients are displayedonly_nonredundant
– (default:True
) boolean; ifTrue
, only nonredundant (w.r.t. the symmetry of the last two indices) connection coefficients are displayed
EXAMPLES:
Christoffel symbols of the flat metric on \(\RR^3\) with respect to spherical coordinates:
sage: M = Manifold(3, 'R3', r'\RR^3', start_index=1) sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0) sage: X.<r,th,ph> = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi') sage: g = U.metric('g') sage: g[1,1], g[2,2], g[3,3] = 1, r^2, r^2*sin(th)^2 sage: g.display() # the standard flat metric expressed in spherical coordinates g = dr*dr + r^2 dth*dth + r^2*sin(th)^2 dph*dph sage: g.christoffel_symbols_display() Gam^r_th,th = -r Gam^r_ph,ph = -r*sin(th)^2 Gam^th_r,th = 1/r Gam^th_ph,ph = -cos(th)*sin(th) Gam^ph_r,ph = 1/r Gam^ph_th,ph = cos(th)/sin(th)
To list all nonzero Christoffel symbols, including those that can be deduced by symmetry, use
only_nonredundant=False
:sage: g.christoffel_symbols_display(only_nonredundant=False) Gam^r_th,th = -r Gam^r_ph,ph = -r*sin(th)^2 Gam^th_r,th = 1/r Gam^th_th,r = 1/r Gam^th_ph,ph = -cos(th)*sin(th) Gam^ph_r,ph = 1/r Gam^ph_th,ph = cos(th)/sin(th) Gam^ph_ph,r = 1/r Gam^ph_ph,th = cos(th)/sin(th)
Listing all Christoffel symbols (except those that can be deduced by symmetry), including the vanishing one:
sage: g.christoffel_symbols_display(only_nonzero=False) Gam^r_r,r = 0 Gam^r_r,th = 0 Gam^r_r,ph = 0 Gam^r_th,th = -r Gam^r_th,ph = 0 Gam^r_ph,ph = -r*sin(th)^2 Gam^th_r,r = 0 Gam^th_r,th = 1/r Gam^th_r,ph = 0 Gam^th_th,th = 0 Gam^th_th,ph = 0 Gam^th_ph,ph = -cos(th)*sin(th) Gam^ph_r,r = 0 Gam^ph_r,th = 0 Gam^ph_r,ph = 1/r Gam^ph_th,th = 0 Gam^ph_th,ph = cos(th)/sin(th) Gam^ph_ph,ph = 0
Using integer labels:
sage: g.christoffel_symbols_display(coordinate_labels=False) Gam^1_22 = -r Gam^1_33 = -r*sin(th)^2 Gam^2_12 = 1/r Gam^2_33 = -cos(th)*sin(th) Gam^3_13 = 1/r Gam^3_23 = cos(th)/sin(th)
-
connection
(name=None, latex_name=None, init_coef=True)¶ Return the unique torsion-free affine connection compatible with
self
.This is the so-called Levi-Civita connection.
INPUT:
name
– (default:None
) name given to the Levi-Civita connection; ifNone
, it is formed from the metric namelatex_name
– (default:None
) LaTeX symbol to denote the Levi-Civita connection; ifNone
, it is set toname
, or if the latter is None as well, it formed from the symbol \(\nabla\) and the metric symbolinit_coef
– (default:True
) determines whether the connection coefficients are initialized, as Christoffel symbols in the top charts of the domain ofself
(i.e. disregarding the subcharts)
OUTPUT:
the Levi-Civita connection, as an instance of
LeviCivitaConnection
EXAMPLES:
Levi-Civita connection associated with the Euclidean metric on \(\RR^3\):
sage: M = Manifold(3, 'R^3', start_index=1)
Let us use spherical coordinates on \(\RR^3\):
sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0) sage: c_spher.<r,th,ph> = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi') sage: g = U.metric('g') sage: g[1,1], g[2,2], g[3,3] = 1, r^2 , (r*sin(th))^2 # the Euclidean metric sage: g.connection() Levi-Civita connection nabla_g associated with the Riemannian metric g on the Open subset U of the 3-dimensional differentiable manifold R^3 sage: g.connection().display() # Nonzero connection coefficients Gam^r_th,th = -r Gam^r_ph,ph = -r*sin(th)^2 Gam^th_r,th = 1/r Gam^th_th,r = 1/r Gam^th_ph,ph = -cos(th)*sin(th) Gam^ph_r,ph = 1/r Gam^ph_th,ph = cos(th)/sin(th) Gam^ph_ph,r = 1/r Gam^ph_ph,th = cos(th)/sin(th)
Test of compatibility with the metric:
sage: Dg = g.connection()(g) ; Dg Tensor field nabla_g(g) of type (0,3) on the Open subset U of the 3-dimensional differentiable manifold R^3 sage: Dg == 0 True sage: Dig = g.connection()(g.inverse()) ; Dig Tensor field nabla_g(inv_g) of type (2,1) on the Open subset U of the 3-dimensional differentiable manifold R^3 sage: Dig == 0 True
-
cotton
(name=None, latex_name=None)¶ Return the Cotton conformal tensor associated with the metric. The tensor has type (0,3) and is defined in terms of the Schouten tensor \(S\) (see
schouten()
):\[C_{ijk} = (n-2) \left(\nabla_k S_{ij} - \nabla_j S_{ik}\right)\]INPUT:
name
– (default:None
) name given to the Cotton conformal tensor; ifNone
, it is set to “Cot(g)”, where “g” is the metric’s namelatex_name
– (default:None
) LaTeX symbol to denote the Cotton conformal tensor; ifNone
, it is set to “\mathrm{Cot}(g)”, where “g” is the metric’s name
OUTPUT:
the Cotton conformal tensor \(Cot\), as an instance of
TensorField
EXAMPLES:
Checking that the Cotton tensor identically vanishes on a conformally flat 3-dimensional manifold, for instance the hyperbolic space \(H^3\):
sage: M = Manifold(3, 'H^3', start_index=1) sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0) sage: X.<rh,th,ph> = U.chart(r'rh:(0,+oo):\rho th:(0,pi):\theta ph:(0,2*pi):\phi') sage: g = U.metric('g') sage: b = var('b') sage: g[1,1], g[2,2], g[3,3] = b^2, (b*sinh(rh))^2, (b*sinh(rh)*sin(th))^2 sage: g.display() # standard metric on H^3: g = b^2 drh*drh + b^2*sinh(rh)^2 dth*dth + b^2*sin(th)^2*sinh(rh)^2 dph*dph sage: Cot = g.cotton() ; Cot # long time Tensor field Cot(g) of type (0,3) on the Open subset U of the 3-dimensional differentiable manifold H^3 sage: Cot == 0 # long time True
-
cotton_york
(name=None, latex_name=None)¶ Return the Cotton-York conformal tensor associated with the metric. The tensor has type (0,2) and is only defined for manifolds of dimension 3. It is defined in terms of the Cotton tensor \(C\) (see
cotton()
) or the Schouten tensor \(S\) (seeschouten()
):\[CY_{ij} = \frac{1}{2} \epsilon^{kl}_{\ \ \, i} C_{jlk} = \epsilon^{kl}_{\ \ \, i} \nabla_k S_{lj}\]INPUT:
name
– (default:None
) name given to the Cotton-York tensor; ifNone
, it is set to “CY(g)”, where “g” is the metric’s namelatex_name
– (default:None
) LaTeX symbol to denote the Cotton-York tensor; ifNone
, it is set to “\mathrm{CY}(g)”, where “g” is the metric’s name
OUTPUT:
the Cotton-York conformal tensor \(CY\), as an instance of
TensorField
EXAMPLES:
Compute the determinant of the Cotton-York tensor for the Heisenberg group with the left invariant metric:
sage: M = Manifold(3, 'Nil', start_index=1) sage: X.<x,y,z> = M.chart() sage: g = M.riemannian_metric('g') sage: g[1,1], g[2,2], g[2,3], g[3,3] = 1, 1+x^2, -x, 1 sage: g.display() g = dx*dx + (x^2 + 1) dy*dy - x dy*dz - x dz*dy + dz*dz sage: CY = g.cotton_york() ; CY # long time Tensor field CY(g) of type (0,2) on the 3-dimensional differentiable manifold Nil sage: CY.display() # long time CY(g) = 1/2 dx*dx + (-x^2 + 1/2) dy*dy + x dy*dz + x dz*dy - dz*dz sage: det(CY[:]) # long time -1/4
-
det
(frame=None)¶ Determinant of the metric components in the specified frame.
INPUT:
frame
– (default:None
) vector frame with respect to which the components \(g_{ij}\) of the metric are defined; ifNone
, the default frame of the metric’s domain is used. If a chart is provided instead of a frame, the associated coordinate frame is used
OUTPUT:
the determinant \(\det (g_{ij})\), as an instance of
DiffScalarField
EXAMPLES:
Metric determinant on a 2-dimensional manifold:
sage: M = Manifold(2, 'M', start_index=1) sage: X.<x,y> = M.chart() sage: g = M.metric('g') sage: g[1,1], g[1, 2], g[2, 2] = 1+x, x*y , 1-y sage: g[:] [ x + 1 x*y] [ x*y -y + 1] sage: s = g.determinant() # determinant in M's default frame sage: s.expr() -x^2*y^2 - (x + 1)*y + x + 1
A shortcut is
det()
:sage: g.det() == g.determinant() True
The notation
det(g)
can be used:sage: det(g) == g.determinant() True
Determinant in a frame different from the default’s one:
sage: Y.<u,v> = M.chart() sage: ch_X_Y = X.transition_map(Y, [x+y, x-y]) sage: ch_X_Y.inverse() Change of coordinates from Chart (M, (u, v)) to Chart (M, (x, y)) sage: g.comp(Y.frame())[:, Y] [ 1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2 1/4*u] [ 1/4*u -1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2] sage: g.determinant(Y.frame()).expr() -1/4*x^2*y^2 - 1/4*(x + 1)*y + 1/4*x + 1/4 sage: g.determinant(Y.frame()).expr(Y) -1/64*u^4 - 1/64*v^4 + 1/32*(u^2 + 2)*v^2 - 1/16*u^2 + 1/4*v + 1/4
A chart can be passed instead of a frame:
sage: g.determinant(X) is g.determinant(X.frame()) True sage: g.determinant(Y) is g.determinant(Y.frame()) True
The metric determinant depends on the frame:
sage: g.determinant(X.frame()) == g.determinant(Y.frame()) False
Using SymPy as symbolic engine:
sage: M.set_calculus_method('sympy') sage: g = M.metric('g') sage: g[1,1], g[1, 2], g[2, 2] = 1+x, x*y , 1-y sage: s = g.determinant() # determinant in M's default frame sage: s.expr() -x**2*y**2 + x - y*(x + 1) + 1
-
determinant
(frame=None)¶ Determinant of the metric components in the specified frame.
INPUT:
frame
– (default:None
) vector frame with respect to which the components \(g_{ij}\) of the metric are defined; ifNone
, the default frame of the metric’s domain is used. If a chart is provided instead of a frame, the associated coordinate frame is used
OUTPUT:
the determinant \(\det (g_{ij})\), as an instance of
DiffScalarField
EXAMPLES:
Metric determinant on a 2-dimensional manifold:
sage: M = Manifold(2, 'M', start_index=1) sage: X.<x,y> = M.chart() sage: g = M.metric('g') sage: g[1,1], g[1, 2], g[2, 2] = 1+x, x*y , 1-y sage: g[:] [ x + 1 x*y] [ x*y -y + 1] sage: s = g.determinant() # determinant in M's default frame sage: s.expr() -x^2*y^2 - (x + 1)*y + x + 1
A shortcut is
det()
:sage: g.det() == g.determinant() True
The notation
det(g)
can be used:sage: det(g) == g.determinant() True
Determinant in a frame different from the default’s one:
sage: Y.<u,v> = M.chart() sage: ch_X_Y = X.transition_map(Y, [x+y, x-y]) sage: ch_X_Y.inverse() Change of coordinates from Chart (M, (u, v)) to Chart (M, (x, y)) sage: g.comp(Y.frame())[:, Y] [ 1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2 1/4*u] [ 1/4*u -1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2] sage: g.determinant(Y.frame()).expr() -1/4*x^2*y^2 - 1/4*(x + 1)*y + 1/4*x + 1/4 sage: g.determinant(Y.frame()).expr(Y) -1/64*u^4 - 1/64*v^4 + 1/32*(u^2 + 2)*v^2 - 1/16*u^2 + 1/4*v + 1/4
A chart can be passed instead of a frame:
sage: g.determinant(X) is g.determinant(X.frame()) True sage: g.determinant(Y) is g.determinant(Y.frame()) True
The metric determinant depends on the frame:
sage: g.determinant(X.frame()) == g.determinant(Y.frame()) False
Using SymPy as symbolic engine:
sage: M.set_calculus_method('sympy') sage: g = M.metric('g') sage: g[1,1], g[1, 2], g[2, 2] = 1+x, x*y , 1-y sage: s = g.determinant() # determinant in M's default frame sage: s.expr() -x**2*y**2 + x - y*(x + 1) + 1
-
hodge_star
(pform)¶ Compute the Hodge dual of a differential form with respect to the metric.
If the differential form is a \(p\)-form \(A\), its Hodge dual with respect to the metric \(g\) is the \((n-p)\)-form \(*A\) defined by
\[*A_{i_1\ldots i_{n-p}} = \frac{1}{p!} A_{k_1\ldots k_p} \epsilon^{k_1\ldots k_p}_{\qquad\ i_1\ldots i_{n-p}}\]where \(n\) is the manifold’s dimension, \(\epsilon\) is the volume \(n\)-form associated with \(g\) (see
volume_form()
) and the indices \(k_1,\ldots, k_p\) are raised with \(g\).Notice that that the hodge star dual requires an orientable manifold with a preferred orientation, see
orientation()
for details.INPUT:
pform
: a \(p\)-form \(A\); must be an instance ofDiffScalarField
for \(p=0\) and ofDiffForm
orDiffFormParal
for \(p\geq 1\).
OUTPUT:
the \((n-p)\)-form \(*A\)
EXAMPLES:
Hodge dual of a 1-form 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: var('Ax Ay Az') (Ax, Ay, Az) sage: a = M.one_form(Ax, Ay, Az, name='A') sage: sa = g.hodge_star(a) ; sa 2-form *A on the 3-dimensional differentiable manifold M sage: sa.display() *A = Az dx/\dy - Ay dx/\dz + Ax dy/\dz sage: ssa = g.hodge_star(sa) ; ssa 1-form **A on the 3-dimensional differentiable manifold M sage: ssa.display() **A = Ax dx + Ay dy + Az dz sage: ssa == a # must hold for a Riemannian metric in dimension 3 True
Hodge dual of a 0-form (scalar field) in \(R^3\):
sage: f = M.scalar_field(function('F')(x,y,z), name='f') sage: sf = g.hodge_star(f) ; sf 3-form *f on the 3-dimensional differentiable manifold M sage: sf.display() *f = F(x, y, z) dx/\dy/\dz sage: ssf = g.hodge_star(sf) ; 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
Hodge dual of a 0-form in Minkowski spacetime:
sage: M = Manifold(4, 'M') sage: X.<t,x,y,z> = M.chart() sage: g = M.lorentzian_metric('g') sage: g[0,0], g[1,1], g[2,2], g[3,3] = -1, 1, 1, 1 sage: g.display() # Minkowski metric g = -dt*dt + dx*dx + dy*dy + dz*dz sage: var('f0') f0 sage: f = M.scalar_field(f0, name='f') sage: sf = g.hodge_star(f) ; sf 4-form *f on the 4-dimensional differentiable manifold M sage: sf.display() *f = f0 dt/\dx/\dy/\dz sage: ssf = g.hodge_star(sf) ; ssf Scalar field **f on the 4-dimensional differentiable manifold M sage: ssf.display() **f: M --> R (t, x, y, z) |--> -f0 sage: ssf == -f # must hold for a Lorentzian metric True
Hodge dual of a 1-form in Minkowski spacetime:
sage: var('At Ax Ay Az') (At, Ax, Ay, Az) sage: a = M.one_form(At, Ax, Ay, Az, name='A') sage: a.display() A = At dt + Ax dx + Ay dy + Az dz sage: sa = g.hodge_star(a) ; sa 3-form *A on the 4-dimensional differentiable manifold M sage: sa.display() *A = -Az dt/\dx/\dy + Ay dt/\dx/\dz - Ax dt/\dy/\dz - At dx/\dy/\dz sage: ssa = g.hodge_star(sa) ; ssa 1-form **A on the 4-dimensional differentiable manifold M sage: ssa.display() **A = At dt + Ax dx + Ay dy + Az dz sage: ssa == a # must hold for a Lorentzian metric in dimension 4 True
Hodge dual of a 2-form in Minkowski spacetime:
sage: F = M.diff_form(2, name='F') sage: var('Ex Ey Ez Bx By Bz') (Ex, Ey, Ez, Bx, By, Bz) sage: F[0,1], F[0,2], F[0,3] = -Ex, -Ey, -Ez sage: F[1,2], F[1,3], F[2,3] = Bz, -By, Bx sage: F[:] [ 0 -Ex -Ey -Ez] [ Ex 0 Bz -By] [ Ey -Bz 0 Bx] [ Ez By -Bx 0] sage: sF = g.hodge_star(F) ; sF 2-form *F on the 4-dimensional differentiable manifold M sage: sF[:] [ 0 Bx By Bz] [-Bx 0 Ez -Ey] [-By -Ez 0 Ex] [-Bz Ey -Ex 0] sage: ssF = g.hodge_star(sF) ; ssF 2-form **F on the 4-dimensional differentiable manifold M sage: ssF[:] [ 0 Ex Ey Ez] [-Ex 0 -Bz By] [-Ey Bz 0 -Bx] [-Ez -By Bx 0] sage: ssF.display() **F = Ex dt/\dx + Ey dt/\dy + Ez dt/\dz - Bz dx/\dy + By dx/\dz - Bx dy/\dz sage: F.display() F = -Ex dt/\dx - Ey dt/\dy - Ez dt/\dz + Bz dx/\dy - By dx/\dz + Bx dy/\dz sage: ssF == -F # must hold for a Lorentzian metric in dimension 4 True
Test of the standard identity
\[*(A\wedge B) = \epsilon(A^\sharp, B^\sharp, ., .)\]where \(A\) and \(B\) are any 1-forms and \(A^\sharp\) and \(B^\sharp\) the vectors associated to them by the metric \(g\) (index raising):
sage: var('Bt Bx By Bz') (Bt, Bx, By, Bz) sage: b = M.one_form(Bt, Bx, By, Bz, name='B') sage: b.display() B = Bt dt + Bx dx + By dy + Bz dz sage: epsilon = g.volume_form() sage: g.hodge_star(a.wedge(b)) == epsilon.contract(0,a.up(g)).contract(0,b.up(g)) True
-
inverse
(expansion_symbol=None, order=1)¶ Return the inverse metric.
INPUT:
expansion_symbol
– (default:None
) symbolic variable; if specified, the inverse will be expanded in power series with respect to this variable (around its zero value)order
– integer (default: 1); the order of the expansion ifexpansion_symbol
is notNone
; the order is defined as the degree of the polynomial representing the truncated power series inexpansion_symbol
; currently only first order inverse is supported
If
expansion_symbol
is set, then the zeroth order metric must be invertible. Moreover, subsequent calls to this method will return a cached value, even when called with the default value (to enable computation of derived quantities). To reset, use_del_derived()
.OUTPUT:
instance of
TensorField
withtensor_type
= (2,0) representing the inverse metric
EXAMPLES:
Inverse of the standard metric on the 2-sphere:
sage: M = Manifold(2, 'S^2', start_index=1) sage: U = M.open_subset('U') ; V = M.open_subset('V') sage: M.declare_union(U,V) # S^2 is the union of U and V sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart() # stereographic coord. 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: W = U.intersection(V) # the complement of the two poles sage: eU = c_xy.frame() ; eV = c_uv.frame() sage: g = M.metric('g') sage: g[eU,1,1], g[eU,2,2] = 4/(1+x^2+y^2)^2, 4/(1+x^2+y^2)^2 sage: g.add_comp_by_continuation(eV, W, c_uv) sage: ginv = g.inverse(); ginv Tensor field inv_g of type (2,0) on the 2-dimensional differentiable manifold S^2 sage: ginv.display(eU) inv_g = (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) d/dx*d/dx + (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) d/dy*d/dy sage: ginv.display(eV) inv_g = (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) d/du*d/du + (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) d/dv*d/dv
Let us check that
ginv
is indeed the inverse ofg
:sage: s = g.contract(ginv); s # contraction of last index of g with first index of ginv Tensor field of type (1,1) on the 2-dimensional differentiable manifold S^2 sage: s == M.tangent_identity_field() True
-
restrict
(subdomain, dest_map=None)¶ Return the restriction of the metric to some subdomain.
If the restriction has not been defined yet, it is constructed here.
INPUT:
subdomain
– open subset \(U\) of the metric’s domain (must be an instance ofDifferentiableManifold
)dest_map
– (default:None
) destination map \(\Phi:\ U \rightarrow V\), where \(V\) is a subdomain ofself._codomain
(type:DiffMap
) If None, the restriction ofself._vmodule._dest_map
to \(U\) is used.
OUTPUT:
instance of
PseudoRiemannianMetric
representing the restriction.
EXAMPLES:
sage: M = Manifold(5, 'M') sage: g = M.metric('g', signature=3) sage: U = M.open_subset('U') sage: g.restrict(U) Lorentzian metric g on the Open subset U of the 5-dimensional differentiable manifold M sage: g.restrict(U).signature() 3
See the top documentation of
PseudoRiemannianMetric
for more examples.
-
ricci
(name=None, latex_name=None)¶ Return the Ricci tensor associated with the metric.
This method is actually a shortcut for
self.connection().ricci()
The Ricci tensor is the tensor field \(Ric\) of type (0,2) defined from the Riemann curvature tensor \(R\) by
\[Ric(u, v) = R(e^i, u, e_i, v)\]for any vector fields \(u\) and \(v\), \((e_i)\) being any vector frame and \((e^i)\) the dual coframe.
INPUT:
name
– (default:None
) name given to the Ricci tensor; if none, it is set to “Ric(g)”, where “g” is the metric’s namelatex_name
– (default:None
) LaTeX symbol to denote the Ricci tensor; if none, it is set to “\mathrm{Ric}(g)”, where “g” is the metric’s name
OUTPUT:
the Ricci tensor \(Ric\), as an instance of
TensorField
of tensor type (0,2) and symmetric
EXAMPLES:
Ricci tensor of the standard metric on the 2-sphere:
sage: M = Manifold(2, 'S^2', start_index=1) sage: U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates) sage: c_spher.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi') sage: a = var('a') # the sphere radius sage: g = U.metric('g') sage: g[1,1], g[2,2] = a^2, a^2*sin(th)^2 sage: g.display() # standard metric on the 2-sphere of radius a: g = a^2 dth*dth + a^2*sin(th)^2 dph*dph sage: g.ricci() Field of symmetric bilinear forms Ric(g) on the Open subset U of the 2-dimensional differentiable manifold S^2 sage: g.ricci()[:] [ 1 0] [ 0 sin(th)^2] sage: g.ricci() == a^(-2) * g True
-
ricci_scalar
(name=None, latex_name=None)¶ Return the Ricci scalar associated with the metric.
The Ricci scalar is the scalar field \(r\) defined from the Ricci tensor \(Ric\) and the metric tensor \(g\) by
\[r = g^{ij} Ric_{ij}\]INPUT:
name
– (default:None
) name given to the Ricci scalar; if none, it is set to “r(g)”, where “g” is the metric’s namelatex_name
– (default:None
) LaTeX symbol to denote the Ricci scalar; if none, it is set to “\mathrm{r}(g)”, where “g” is the metric’s name
OUTPUT:
the Ricci scalar \(r\), as an instance of
DiffScalarField
EXAMPLES:
Ricci scalar of the standard metric on the 2-sphere:
sage: M = Manifold(2, 'S^2', start_index=1) sage: U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates) sage: c_spher.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi') sage: a = var('a') # the sphere radius sage: g = U.metric('g') sage: g[1,1], g[2,2] = a^2, a^2*sin(th)^2 sage: g.display() # standard metric on the 2-sphere of radius a: g = a^2 dth*dth + a^2*sin(th)^2 dph*dph sage: g.ricci_scalar() Scalar field r(g) on the Open subset U of the 2-dimensional differentiable manifold S^2 sage: g.ricci_scalar().display() # The Ricci scalar is constant: r(g): U --> R (th, ph) |--> 2/a^2
-
riemann
(name=None, latex_name=None)¶ Return the Riemann curvature tensor associated with the metric.
This method is actually a shortcut for
self.connection().riemann()
The Riemann curvature tensor is the tensor field \(R\) of type (1,3) defined by
\[R(\omega, u, v, w) = \left\langle \omega, \nabla_u \nabla_v w - \nabla_v \nabla_u w - \nabla_{[u, v]} w \right\rangle\]for any 1-form \(\omega\) and any vector fields \(u\), \(v\) and \(w\).
INPUT:
name
– (default:None
) name given to the Riemann tensor; if none, it is set to “Riem(g)”, where “g” is the metric’s namelatex_name
– (default:None
) LaTeX symbol to denote the Riemann tensor; if none, it is set to “\mathrm{Riem}(g)”, where “g” is the metric’s name
OUTPUT:
the Riemann curvature tensor \(R\), as an instance of
TensorField
EXAMPLES:
Riemann tensor of the standard metric on the 2-sphere:
sage: M = Manifold(2, 'S^2', start_index=1) sage: U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates) sage: c_spher.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi') sage: a = var('a') # the sphere radius sage: g = U.metric('g') sage: g[1,1], g[2,2] = a^2, a^2*sin(th)^2 sage: g.display() # standard metric on the 2-sphere of radius a: g = a^2 dth*dth + a^2*sin(th)^2 dph*dph sage: g.riemann() Tensor field Riem(g) of type (1,3) on the Open subset U of the 2-dimensional differentiable manifold S^2 sage: g.riemann()[:] [[[[0, 0], [0, 0]], [[0, sin(th)^2], [-sin(th)^2, 0]]], [[[0, -1], [1, 0]], [[0, 0], [0, 0]]]]
In dimension 2, the Riemann tensor can be expressed entirely in terms of the Ricci scalar \(r\):
\[R^i_{\ \, jlk} = \frac{r}{2} \left( \delta^i_{\ \, k} g_{jl} - \delta^i_{\ \, l} g_{jk} \right)\]This formula can be checked here, with the r.h.s. rewritten as \(-r g_{j[k} \delta^i_{\ \, l]}\):
sage: g.riemann() == \ ....: -g.ricci_scalar()*(g*U.tangent_identity_field()).antisymmetrize(2,3) True
Using SymPy as symbolic engine:
sage: M.set_calculus_method('sympy') sage: g = U.metric('g') sage: g[1,1], g[2,2] = a**2, a**2*sin(th)**2 sage: g.riemann()[:] [[[[0, 0], [0, 0]], [[0, sin(2*th)/(2*tan(th)) - cos(2*th)], [-sin(2*th)/(2*tan(th)) + cos(2*th), 0]]], [[[0, -1], [1, 0]], [[0, 0], [0, 0]]]]
-
schouten
(name=None, latex_name=None)¶ Return the Schouten tensor associated with the metric.
The Schouten tensor is the tensor field \(Sc\) of type (0,2) defined from the Ricci curvature tensor \(Ric\) (see
ricci()
) and the scalar curvature \(r\) (seericci_scalar()
) and the metric \(g\) by\[Sc(u, v) = \frac{1}{n-2}\left(Ric(u, v) + \frac{r}{2(n-1)}g(u,v) \right)\]for any vector fields \(u\) and \(v\).
INPUT:
name
– (default:None
) name given to the Schouten tensor; if none, it is set to “Schouten(g)”, where “g” is the metric’s namelatex_name
– (default:None
) LaTeX symbol to denote the Schouten tensor; if none, it is set to “\mathrm{Schouten}(g)”, where “g” is the metric’s name
OUTPUT:
the Schouten tensor \(Sc\), as an instance of
TensorField
of tensor type (0,2) and symmetric
EXAMPLES:
Schouten tensor of the left invariant metric of Heisenberg’s Nil group:
sage: M = Manifold(3, 'Nil', start_index=1) sage: X.<x,y,z> = M.chart() sage: g = M.riemannian_metric('g') sage: g[1,1], g[2,2], g[2,3], g[3,3] = 1, 1+x^2, -x, 1 sage: g.display() g = dx*dx + (x^2 + 1) dy*dy - x dy*dz - x dz*dy + dz*dz sage: g.schouten() Field of symmetric bilinear forms Schouten(g) on the 3-dimensional differentiable manifold Nil sage: g.schouten().display() Schouten(g) = -3/8 dx*dx + (5/8*x^2 - 3/8) dy*dy - 5/8*x dy*dz - 5/8*x dz*dy + 5/8 dz*dz
-
set
(symbiform)¶ Defines the metric from a field of symmetric bilinear forms
INPUT:
symbiform
– instance ofTensorField
representing a field of symmetric bilinear forms
EXAMPLES:
Metric defined from a field of symmetric bilinear forms on a non-parallelizable 2-dimensional manifold:
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_uv.<u,v> = V.chart() sage: xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W', ....: restrictions1= x>0, restrictions2= u+v>0) sage: uv_to_xy = xy_to_uv.inverse() sage: W = U.intersection(V) sage: eU = c_xy.frame() ; eV = c_uv.frame() sage: h = M.sym_bilin_form_field(name='h') sage: h[eU,0,0], h[eU,0,1], h[eU,1,1] = 1+x, x*y, 1-y sage: h.add_comp_by_continuation(eV, W, c_uv) sage: h.display(eU) h = (x + 1) dx*dx + x*y dx*dy + x*y dy*dx + (-y + 1) dy*dy sage: h.display(eV) h = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du*du + 1/4*u du*dv + 1/4*u dv*du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv*dv sage: g = M.metric('g') sage: g.set(h) sage: g.display(eU) g = (x + 1) dx*dx + x*y dx*dy + x*y dy*dx + (-y + 1) dy*dy sage: g.display(eV) g = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du*du + 1/4*u du*dv + 1/4*u dv*du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv*dv
-
signature
()¶ Signature of the metric.
OUTPUT:
signature \(S\) of the metric, defined as the integer \(S = n_+ - n_-\), where \(n_+\) (resp. \(n_-\)) is the number of positive terms (resp. number of negative terms) in any diagonal writing of the metric components
EXAMPLES:
Signatures on a 2-dimensional manifold:
sage: M = Manifold(2, 'M') sage: g = M.metric('g') # if not specified, the signature is Riemannian sage: g.signature() 2 sage: h = M.metric('h', signature=0) sage: h.signature() 0
-
sqrt_abs_det
(frame=None)¶ Square root of the absolute value of the determinant of the metric components in the specified frame.
INPUT:
frame
– (default:None
) vector frame with respect to which the components \(g_{ij}\) ofself
are defined; ifNone
, the domain’s default frame is used. If a chart is provided, the associated coordinate frame is used
OUTPUT:
\(\sqrt{|\det (g_{ij})|}\), as an instance of
DiffScalarField
EXAMPLES:
Standard metric in the Euclidean space \(\RR^3\) with spherical coordinates:
sage: M = Manifold(3, 'M', start_index=1) sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0) sage: c_spher.<r,th,ph> = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi') sage: g = U.metric('g') sage: g[1,1], g[2,2], g[3,3] = 1, r^2, (r*sin(th))^2 sage: g.display() g = dr*dr + r^2 dth*dth + r^2*sin(th)^2 dph*dph sage: g.sqrt_abs_det().expr() r^2*sin(th)
Metric determinant on a 2-dimensional manifold:
sage: M = Manifold(2, 'M', start_index=1) sage: X.<x,y> = M.chart() sage: g = M.metric('g') sage: g[1,1], g[1, 2], g[2, 2] = 1+x, x*y , 1-y sage: g[:] [ x + 1 x*y] [ x*y -y + 1] sage: s = g.sqrt_abs_det() ; s Scalar field on the 2-dimensional differentiable manifold M sage: s.expr() sqrt(-x^2*y^2 - (x + 1)*y + x + 1)
Determinant in a frame different from the default’s one:
sage: Y.<u,v> = M.chart() sage: ch_X_Y = X.transition_map(Y, [x+y, x-y]) sage: ch_X_Y.inverse() Change of coordinates from Chart (M, (u, v)) to Chart (M, (x, y)) sage: g[Y.frame(),:,Y] [ 1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2 1/4*u] [ 1/4*u -1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2] sage: g.sqrt_abs_det(Y.frame()).expr() 1/2*sqrt(-x^2*y^2 - (x + 1)*y + x + 1) sage: g.sqrt_abs_det(Y.frame()).expr(Y) 1/8*sqrt(-u^4 - v^4 + 2*(u^2 + 2)*v^2 - 4*u^2 + 16*v + 16)
A chart can be passed instead of a frame:
sage: g.sqrt_abs_det(Y) is g.sqrt_abs_det(Y.frame()) True
The metric determinant depends on the frame:
sage: g.sqrt_abs_det(X.frame()) == g.sqrt_abs_det(Y.frame()) False
Using SymPy as symbolic engine:
sage: M.set_calculus_method('sympy') sage: g = M.metric('g') sage: g[1,1], g[1, 2], g[2, 2] = 1+x, x*y , 1-y sage: g.sqrt_abs_det().expr() sqrt(-x**2*y**2 - x*y + x - y + 1) sage: g.sqrt_abs_det(Y.frame()).expr() sqrt(-x**2*y**2 - x*y + x - y + 1)/2 sage: g.sqrt_abs_det(Y.frame()).expr(Y) sqrt(-u**4 + 2*u**2*v**2 - 4*u**2 - v**4 + 4*v**2 + 16*v + 16)/8
-
volume_form
(contra=0)¶ Volume form (Levi-Civita tensor) \(\epsilon\) associated with the metric.
The volume form \(\epsilon\) is an \(n\)-form (\(n\) being the manifold’s dimension) such that for any oriented vector basis \((e_i)\) which is orthonormal with respect to the metric, the condition
\[\epsilon(e_1,\ldots,e_n) = 1\]holds.
Notice that that a volume form requires an orientable manifold with a preferred orientation, see
orientation()
for details.INPUT:
contra
– (default: 0) number of contravariant indices of the returned tensor
OUTPUT:
if
contra = 0
(default value): the volume \(n\)-form \(\epsilon\), as an instance ofDiffForm
if
contra = k
, with \(1\leq k \leq n\), the tensor field of type (k,n-k) formed from \(\epsilon\) by raising the first k indices with the metric (see methodup()
); the output is then an instance ofTensorField
, with the appropriate antisymmetries, or of the subclassMultivectorField
if \(k=n\)
EXAMPLES:
Volume form on \(\RR^3\) with spherical coordinates, using the standard orientation, which is predefined:
sage: M = Manifold(3, 'M', start_index=1) sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0) sage: c_spher.<r,th,ph> = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi') sage: g = U.metric('g') sage: g[1,1], g[2,2], g[3,3] = 1, r^2, (r*sin(th))^2 sage: g.display() g = dr*dr + r^2 dth*dth + r^2*sin(th)^2 dph*dph sage: eps = g.volume_form() ; eps 3-form eps_g on the Open subset U of the 3-dimensional differentiable manifold M sage: eps.display() eps_g = r^2*sin(th) dr/\dth/\dph sage: eps[[1,2,3]] == g.sqrt_abs_det() True sage: latex(eps) \epsilon_{g}
The tensor field of components \(\epsilon^i_{\ \, jk}\) (
contra=1
):sage: eps1 = g.volume_form(1) ; eps1 Tensor field of type (1,2) on the Open subset U of the 3-dimensional differentiable manifold M sage: eps1.symmetries() no symmetry; antisymmetry: (1, 2) sage: eps1[:] [[[0, 0, 0], [0, 0, r^2*sin(th)], [0, -r^2*sin(th), 0]], [[0, 0, -sin(th)], [0, 0, 0], [sin(th), 0, 0]], [[0, 1/sin(th), 0], [-1/sin(th), 0, 0], [0, 0, 0]]]
The tensor field of components \(\epsilon^{ij}_{\ \ k}\) (
contra=2
):sage: eps2 = g.volume_form(2) ; eps2 Tensor field of type (2,1) on the Open subset U of the 3-dimensional differentiable manifold M sage: eps2.symmetries() no symmetry; antisymmetry: (0, 1) sage: eps2[:] [[[0, 0, 0], [0, 0, sin(th)], [0, -1/sin(th), 0]], [[0, 0, -sin(th)], [0, 0, 0], [1/(r^2*sin(th)), 0, 0]], [[0, 1/sin(th), 0], [-1/(r^2*sin(th)), 0, 0], [0, 0, 0]]]
The tensor field of components \(\epsilon^{ijk}\) (
contra=3
):sage: eps3 = g.volume_form(3) ; eps3 3-vector field on the Open subset U of the 3-dimensional differentiable manifold M sage: eps3.tensor_type() (3, 0) sage: eps3.symmetries() no symmetry; antisymmetry: (0, 1, 2) sage: eps3[:] [[[0, 0, 0], [0, 0, 1/(r^2*sin(th))], [0, -1/(r^2*sin(th)), 0]], [[0, 0, -1/(r^2*sin(th))], [0, 0, 0], [1/(r^2*sin(th)), 0, 0]], [[0, 1/(r^2*sin(th)), 0], [-1/(r^2*sin(th)), 0, 0], [0, 0, 0]]] sage: eps3[1,2,3] 1/(r^2*sin(th)) sage: eps3[[1,2,3]] * g.sqrt_abs_det() == 1 True
If the manifold has no predefined orientation, an orientation must be set before invoking
volume_form()
. For instance let consider the 2-sphere described by the stereographic charts from the North and South pole:sage: M = Manifold(2, 'M', structure='Riemannian') sage: U = M.open_subset('U'); V = M.open_subset('V') sage: M.declare_union(U, V) sage: c_xy.<x,y> = U.chart() # stereographic chart from the North pole sage: c_uv.<u,v> = V.chart() # stereographic chart from the South pole 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: eU = c_xy.frame(); eV = c_uv.frame() sage: g = M.metric() sage: g[eU,0,0], g[eU,1,1] = 4/(1+x^2+y^2)^2, 4/(1+x^2+y^2)^2 sage: g.add_comp_by_continuation(eV, U.intersection(V), chart=c_uv) sage: eps = g.volume_form() Traceback (most recent call last): ... ValueError: 2-dimensional Riemannian manifold M must admit an orientation
Let us define the orientation of
M
such thateU
is right-handed;eV
is then left-handed and in order to define an orientation on the whole ofM
, we introduce a vector frame onV
by swappingeV
’s vectors:sage: f = V.vector_frame('f', (eV[1], eV[0])) sage: M.set_orientation([eU, f])
We have then, factorizing the components for a nicer display:
sage: eps = g.volume_form() sage: eps.apply_map(factor, frame=eU, keep_other_components=True) sage: eps.apply_map(factor, frame=eV, keep_other_components=True) sage: eps.display(eU) eps_g = 4/(x^2 + y^2 + 1)^2 dx/\dy sage: eps.display(eV) eps_g = -4/(u^2 + v^2 + 1)^2 du/\dv
Note the minus sign in the above expression, reflecting the fact that
eV
is left-handed with respect to the chosen orientation.
-
weyl
(name=None, latex_name=None)¶ Return the Weyl conformal tensor associated with the metric.
The Weyl conformal tensor is the tensor field \(C\) of type (1,3) defined as the trace-free part of the Riemann curvature tensor \(R\)
INPUT:
name
– (default:None
) name given to the Weyl conformal tensor; ifNone
, it is set to “C(g)”, where “g” is the metric’s namelatex_name
– (default:None
) LaTeX symbol to denote the Weyl conformal tensor; ifNone
, it is set to “\mathrm{C}(g)”, where “g” is the metric’s name
OUTPUT:
the Weyl conformal tensor \(C\), as an instance of
TensorField
EXAMPLES:
Checking that the Weyl tensor identically vanishes on a 3-dimensional manifold, for instance the hyperbolic space \(H^3\):
sage: M = Manifold(3, 'H^3', start_index=1) sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0) sage: X.<rh,th,ph> = U.chart(r'rh:(0,+oo):\rho th:(0,pi):\theta ph:(0,2*pi):\phi') sage: g = U.metric('g') sage: b = var('b') sage: g[1,1], g[2,2], g[3,3] = b^2, (b*sinh(rh))^2, (b*sinh(rh)*sin(th))^2 sage: g.display() # standard metric on H^3: g = b^2 drh*drh + b^2*sinh(rh)^2 dth*dth + b^2*sin(th)^2*sinh(rh)^2 dph*dph sage: C = g.weyl() ; C Tensor field C(g) of type (1,3) on the Open subset U of the 3-dimensional differentiable manifold H^3 sage: C == 0 True
-
class
sage.manifolds.differentiable.metric.
PseudoRiemannianMetricParal
(vector_field_module, name, signature=None, latex_name=None)¶ Bases:
sage.manifolds.differentiable.metric.PseudoRiemannianMetric
,sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal
Pseudo-Riemannian metric with values on a parallelizable manifold.
An instance of this class is a field of nondegenerate symmetric bilinear forms (metric field) along a differentiable manifold \(U\) with values in a parallelizable manifold \(M\) over \(\RR\), via a differentiable mapping \(\Phi: U \rightarrow M\). The standard case of a metric field on a 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\)).
A metric \(g\) is a field on \(U\), such that at each point \(p\in U\), \(g(p)\) is a bilinear map of the type:
\[g(p):\ T_q M\times T_q M \longrightarrow \RR\]where \(T_q M\) stands for the tangent space to manifold \(M\) at the point \(q=\Phi(p)\), such that \(g(p)\) is symmetric: \(\forall (u,v)\in T_q M\times T_q M, \ g(p)(v,u) = g(p)(u,v)\) and nondegenerate: \((\forall v\in T_q M,\ \ g(p)(u,v) = 0) \Longrightarrow u=0\).
Note
If \(M\) is not parallelizable, the class
PseudoRiemannianMetric
should be used instead.INPUT:
vector_field_module
– free module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(\Phi(U)\subset M\)name
– name given to the metricsignature
– (default:None
) signature \(S\) of the metric as a single integer: \(S = n_+ - n_-\), where \(n_+\) (resp. \(n_-\)) is the number of positive terms (resp. number of negative terms) in any diagonal writing of the metric components; ifsignature
isNone
, \(S\) is set to the dimension of manifold \(M\) (Riemannian signature)latex_name
– (default:None
) LaTeX symbol to denote the metric; ifNone
, it is formed fromname
EXAMPLES:
Metric on a 2-dimensional manifold:
sage: M = Manifold(2, 'M', start_index=1) sage: c_xy.<x,y> = M.chart() sage: g = M.metric('g') ; g Riemannian metric g on the 2-dimensional differentiable manifold M sage: latex(g) g
A metric is a special kind of tensor field and therefore inheritates all the properties from class
TensorField
:sage: g.parent() Free module T^(0,2)(M) of type-(0,2) tensors fields on the 2-dimensional differentiable manifold M sage: g.tensor_type() (0, 2) sage: g.symmetries() # g is symmetric: symmetry: (0, 1); no antisymmetry
Setting the metric components in the manifold’s default frame:
sage: g[1,1], g[1,2], g[2,2] = 1+x, x*y, 1-x sage: g[:] [ x + 1 x*y] [ x*y -x + 1] sage: g.display() g = (x + 1) dx*dx + x*y dx*dy + x*y dy*dx + (-x + 1) dy*dy
Metric components in a frame different from the manifold’s default one:
sage: c_uv.<u,v> = M.chart() # new chart on M sage: xy_to_uv = c_xy.transition_map(c_uv, [x+y, x-y]) ; xy_to_uv Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v)) sage: uv_to_xy = xy_to_uv.inverse() ; uv_to_xy Change of coordinates from Chart (M, (u, v)) to Chart (M, (x, y)) sage: M.atlas() [Chart (M, (x, y)), Chart (M, (u, v))] sage: M.frames() [Coordinate frame (M, (d/dx,d/dy)), Coordinate frame (M, (d/du,d/dv))] sage: g[c_uv.frame(),:] # metric components in frame c_uv.frame() expressed in M's default chart (x,y) [ 1/2*x*y + 1/2 1/2*x] [ 1/2*x -1/2*x*y + 1/2] sage: g.display(c_uv.frame()) g = (1/2*x*y + 1/2) du*du + 1/2*x du*dv + 1/2*x dv*du + (-1/2*x*y + 1/2) dv*dv sage: g[c_uv.frame(),:,c_uv] # metric components in frame c_uv.frame() expressed in chart (u,v) [ 1/8*u^2 - 1/8*v^2 + 1/2 1/4*u + 1/4*v] [ 1/4*u + 1/4*v -1/8*u^2 + 1/8*v^2 + 1/2] sage: g.display(c_uv.frame(), c_uv) g = (1/8*u^2 - 1/8*v^2 + 1/2) du*du + (1/4*u + 1/4*v) du*dv + (1/4*u + 1/4*v) dv*du + (-1/8*u^2 + 1/8*v^2 + 1/2) dv*dv
As a shortcut of the above command, on can pass just the chart
c_uv
todisplay
, the vector frame being then assumed to be the coordinate frame associated with the chart:sage: g.display(c_uv) g = (1/8*u^2 - 1/8*v^2 + 1/2) du*du + (1/4*u + 1/4*v) du*dv + (1/4*u + 1/4*v) dv*du + (-1/8*u^2 + 1/8*v^2 + 1/2) dv*dv
The inverse metric is obtained via
inverse()
:sage: ig = g.inverse() ; ig Tensor field inv_g of type (2,0) on the 2-dimensional differentiable manifold M sage: ig[:] [ (x - 1)/(x^2*y^2 + x^2 - 1) x*y/(x^2*y^2 + x^2 - 1)] [ x*y/(x^2*y^2 + x^2 - 1) -(x + 1)/(x^2*y^2 + x^2 - 1)] sage: ig.display() inv_g = (x - 1)/(x^2*y^2 + x^2 - 1) d/dx*d/dx + x*y/(x^2*y^2 + x^2 - 1) d/dx*d/dy + x*y/(x^2*y^2 + x^2 - 1) d/dy*d/dx - (x + 1)/(x^2*y^2 + x^2 - 1) d/dy*d/dy
-
inverse
(expansion_symbol=None, order=1)¶ Return the inverse metric.
INPUT:
expansion_symbol
– (default:None
) symbolic variable; if specified, the inverse will be expanded in power series with respect to this variable (around its zero value)order
– integer (default: 1); the order of the expansion ifexpansion_symbol
is notNone
; the order is defined as the degree of the polynomial representing the truncated power series inexpansion_symbol
; currently only first order inverse is supported
If
expansion_symbol
is set, then the zeroth order metric must be invertible. Moreover, subsequent calls to this method will return a cached value, even when called with the default value (to enable computation of derived quantities). To reset, use_del_derived()
.OUTPUT:
instance of
TensorFieldParal
withtensor_type
= (2,0) representing the inverse metric
EXAMPLES:
Inverse metric on a 2-dimensional manifold:
sage: M = Manifold(2, 'M', start_index=1) sage: c_xy.<x,y> = M.chart() sage: g = M.metric('g') sage: g[1,1], g[1,2], g[2,2] = 1+x, x*y, 1-x sage: g[:] # components in the manifold's default frame [ x + 1 x*y] [ x*y -x + 1] sage: ig = g.inverse() ; ig Tensor field inv_g of type (2,0) on the 2-dimensional differentiable manifold M sage: ig[:] [ (x - 1)/(x^2*y^2 + x^2 - 1) x*y/(x^2*y^2 + x^2 - 1)] [ x*y/(x^2*y^2 + x^2 - 1) -(x + 1)/(x^2*y^2 + x^2 - 1)]
If the metric is modified, the inverse metric is automatically updated:
sage: g[1,2] = 0 ; g[:] [ x + 1 0] [ 0 -x + 1] sage: g.inverse()[:] [ 1/(x + 1) 0] [ 0 -1/(x - 1)]
Using SymPy as symbolic engine:
sage: M.set_calculus_method('sympy') sage: g[1,1], g[1,2], g[2,2] = 1+x, x*y, 1-x sage: g[:] # components in the manifold's default frame [x + 1 x*y] [ x*y 1 - x] sage: g.inverse()[:] [ (x - 1)/(x**2*y**2 + x**2 - 1) x*y/(x**2*y**2 + x**2 - 1)] [ x*y/(x**2*y**2 + x**2 - 1) -(x + 1)/(x**2*y**2 + x**2 - 1)]
Demonstration of the series expansion capabilities:
sage: M = Manifold(4, 'M', structure='Lorentzian') sage: C.<t,x,y,z> = M.chart() sage: e = var('e') sage: g = M.metric() sage: h = M.tensor_field(0, 2, sym=(0,1)) sage: g[0, 0], g[1, 1], g[2, 2], g[3, 3] = -1, 1, 1, 1 sage: h[0, 1], h[1, 2], h[2, 3] = 1, 1, 1 sage: g.set(g + e*h)
If
e
is a small parameter,g
is a tridiagonal approximation of the Minkowski metric:sage: g[:] [-1 e 0 0] [ e 1 e 0] [ 0 e 1 e] [ 0 0 e 1]
The inverse, truncated to first order in
e
, is:sage: g.inverse(expansion_symbol=e)[:] [-1 e 0 0] [ e 1 -e 0] [ 0 -e 1 -e] [ 0 0 -e 1]
If
inverse()
is called subsequently, the result will be the same. This allows for all computations to be made to first order:sage: g.inverse()[:] [-1 e 0 0] [ e 1 -e 0] [ 0 -e 1 -e] [ 0 0 -e 1]
-
restrict
(subdomain, dest_map=None)¶ Return the restriction of the metric to some subdomain.
If the restriction has not been defined yet, it is constructed here.
INPUT:
subdomain
– open subset \(U\) ofself._domain
(must be an instance ofDifferentiableManifold
)dest_map
– (default:None
) destination map \(\Phi:\ U \rightarrow V\), where \(V\) is a subdomain ofself._codomain
(type:DiffMap
) If None, the restriction ofself._vmodule._dest_map
to \(U\) is used.
OUTPUT:
instance of
PseudoRiemannianMetricParal
representing the restriction.
EXAMPLES:
Restriction of a Lorentzian metric on \(\RR^2\) to the upper half plane:
sage: M = Manifold(2, 'M') sage: X.<x,y> = M.chart() sage: g = M.lorentzian_metric('g') sage: g[0,0], g[1,1] = -1, 1 sage: U = M.open_subset('U', coord_def={X: y>0}) sage: gU = g.restrict(U); gU Lorentzian metric g on the Open subset U of the 2-dimensional differentiable manifold M sage: gU.signature() 0 sage: gU.display() g = -dx*dx + dy*dy
-
ricci_scalar
(name=None, latex_name=None)¶ Return the metric’s Ricci scalar.
The Ricci scalar is the scalar field \(r\) defined from the Ricci tensor \(Ric\) and the metric tensor \(g\) by
\[r = g^{ij} Ric_{ij}\]INPUT:
name
– (default:None
) name given to the Ricci scalar; if none, it is set to “r(g)”, where “g” is the metric’s namelatex_name
– (default:None
) LaTeX symbol to denote the Ricci scalar; if none, it is set to “\mathrm{r}(g)”, where “g” is the metric’s name
OUTPUT:
the Ricci scalar \(r\), as an instance of
DiffScalarField
EXAMPLES:
Ricci scalar of the standard metric on the 2-sphere:
sage: M = Manifold(2, 'S^2', start_index=1) sage: U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates) sage: c_spher.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi') sage: a = var('a') # the sphere radius sage: g = U.metric('g') sage: g[1,1], g[2,2] = a^2, a^2*sin(th)^2 sage: g.display() # standard metric on the 2-sphere of radius a: g = a^2 dth*dth + a^2*sin(th)^2 dph*dph sage: g.ricci_scalar() Scalar field r(g) on the Open subset U of the 2-dimensional differentiable manifold S^2 sage: g.ricci_scalar().display() # The Ricci scalar is constant: r(g): U --> R (th, ph) |--> 2/a^2
-
set
(symbiform)¶ Define the metric from a field of symmetric bilinear forms.
INPUT:
symbiform
– instance ofTensorFieldParal
representing a field of symmetric bilinear forms
EXAMPLES:
sage: M = Manifold(2, 'M') sage: X.<x,y> = M.chart() sage: s = M.sym_bilin_form_field(name='s') sage: s[0,0], s[0,1], s[1,1] = 1+x^2, x*y, 1+y^2 sage: g = M.metric('g') sage: g.set(s) sage: g.display() g = (x^2 + 1) dx*dx + x*y dx*dy + x*y dy*dx + (y^2 + 1) dy*dy