diff --git a/src/sage/manifolds/differentiable/degenerate.py b/src/sage/manifolds/differentiable/degenerate.py index fea96da4fea..aa3a301255b 100644 --- a/src/sage/manifolds/differentiable/degenerate.py +++ b/src/sage/manifolds/differentiable/degenerate.py @@ -31,8 +31,8 @@ class DegenerateManifold(DifferentiableManifold): - ``n`` -- positive integer; dimension of the manifold - ``name`` -- string; name (symbol) given to the manifold - - ``metric_name`` -- (default: ``'g'``) string; name (symbol) given to the - metric + - ``metric_name`` -- (default: ``None``) string; name (symbol) given to the + metric; if ``None``, ``'g'`` is used - ``signature`` -- (default: ``None``) signature `S` of the metric as a 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 @@ -98,12 +98,12 @@ class DegenerateManifold(DifferentiableManifold): - [DB1996]_ - [DS2010]_ """ - def __init__(self, n, name, metric_name='g', signature=None, base_manifold=None, - diff_degree=infinity, latex_name=None, + def __init__(self, n, name, metric_name=None, signature=None, + base_manifold=None, diff_degree=infinity, latex_name=None, metric_latex_name=None, start_index=0, category=None, unique_tag=None): r""" - Construct a pseudo-Riemannian manifold. + Construct a degenerate manifold. TESTS:: @@ -130,7 +130,9 @@ def __init__(self, n, name, metric_name='g', signature=None, base_manifold=None, category=category) self._metric = None # to be initialized by metric() self._metric_signature = signature - if not isinstance(metric_name, str): + if metric_name is None: + metric_name = 'g' + elif not isinstance(metric_name, str): raise TypeError("{} is not a string".format(metric_name)) self._metric_name = metric_name if metric_latex_name is None: diff --git a/src/sage/manifolds/differentiable/degenerate_submanifold.py b/src/sage/manifolds/differentiable/degenerate_submanifold.py index 34a3ce96f75..d5d9c4b8be8 100644 --- a/src/sage/manifolds/differentiable/degenerate_submanifold.py +++ b/src/sage/manifolds/differentiable/degenerate_submanifold.py @@ -182,30 +182,24 @@ class DegenerateSubmanifold(DegenerateManifold, DifferentiableSubmanifold): - ``n`` -- positive integer; dimension of the manifold - ``name`` -- string; name (symbol) given to the manifold - - ``field`` -- field `K` on which the manifold is - defined; allowed values are - - - ``'real'`` or an object of type ``RealField`` (e.g., ``RR``) for - a manifold over `\RR` - - ``'complex'`` or an object of type ``ComplexField`` (e.g., ``CC``) - for a manifold over `\CC` - - an object in the category of topological fields (see - :class:`~sage.categories.fields.Fields` and - :class:`~sage.categories.topological_spaces.TopologicalSpaces`) - for other types of manifolds - + - ``ambient`` -- (default: ``None``) pseudo-Riemannian manifold `M` in + which the submanifold is embedded (or immersed). If ``None``, it is set + to ``self`` + - ``metric_name`` -- (default: ``None``) string; name (symbol) given to the + metric; if ``None``, ``'g'`` is used - ``signature`` -- (default: ``None``) signature `S` of the metric as a 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; if ``signature`` is not provided, `S` is set to `(ndim-1, 0, 1)`, being `ndim` the manifold's dimension - - ``ambient`` -- (default: ``None``) manifold of destination - of the immersion. If ``None``, set to ``self`` - ``base_manifold`` -- (default: ``None``) if not ``None``, must be a topological manifold; the created object is then an open subset of ``base_manifold`` + - ``diff_degree`` -- (default: ``infinity``) degree of differentiability - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote the manifold; if none are provided, it is set to ``name`` + - ``metric_latex_name`` -- (default: ``None``) string; LaTeX symbol to + denote the metric; if none is provided, it is set to ``metric_name`` - ``start_index`` -- (default: 0) integer; lower value of the range of indices used for "indexed objects" on the manifold, e.g., coordinates in a chart @@ -227,12 +221,12 @@ class DegenerateSubmanifold(DegenerateManifold, DifferentiableSubmanifold): :mod:`~sage.manifolds.differentiable.differentiable_submanifold` """ - def __init__(self, n, name, ambient=None, metric_name='g', signature=None, + def __init__(self, n, name, ambient=None, metric_name=None, signature=None, base_manifold=None, diff_degree=infinity, latex_name=None, metric_latex_name=None, start_index=0, category=None, unique_tag=None): r""" - Construct a pseudo-Riemannian submanifold. + Construct a degenerate submanifold. EXAMPLES: @@ -245,7 +239,6 @@ def __init__(self, n, name, ambient=None, metric_name='g', signature=None, differentiable manifold M """ - DegenerateManifold.__init__(self, n, name=name, metric_name=metric_name, signature=signature, diff --git a/src/sage/manifolds/differentiable/examples/sphere.py b/src/sage/manifolds/differentiable/examples/sphere.py index 4d922c45792..9dbdf3bdd40 100644 --- a/src/sage/manifolds/differentiable/examples/sphere.py +++ b/src/sage/manifolds/differentiable/examples/sphere.py @@ -52,14 +52,14 @@ As a submanifold of a Riemannian manifold, namely the Euclidean space, the 2-sphere admits an induced metric:: - sage: h = S2_r.induced_metric() - sage: h.display() - gamma = r^2 dtheta⊗dtheta + r^2*sin(theta)^2 dphi⊗dphi + sage: g = S2_r.induced_metric() + sage: g.display() + g = r^2 dtheta⊗dtheta + r^2*sin(theta)^2 dphi⊗dphi The induced metric is also known as the *first fundamental form* (see :meth:`~sage.manifolds.differentiable.pseudo_riemannian_submanifold.PseudoRiemannianSubmanifold.first_fundamental_form`):: - sage: h is S2_r.first_fundamental_form() + sage: g is S2_r.first_fundamental_form() True The *second fundamental form* encodes the extrinsic curvature of the @@ -157,12 +157,12 @@ vector field pointing outwards. Henceforth, the manifold admits a volume form:: - sage: h = S1c.induced_metric() - sage: h.display() - gamma = dchi⊗dchi - sage: eps = h.volume_form() + sage: g = S1c.induced_metric() + sage: g.display() + g = dchi⊗dchi + sage: eps = g.volume_form() sage: eps.display() - eps_gamma = -dchi + eps_g = -dchi """ @@ -380,7 +380,8 @@ def __init__(self, n, radius=1, ambient_space=None, center=None, name=None, PseudoRiemannianSubmanifold.__init__(self, n, name, ambient=ambient_space, signature=n, latex_name=latex_name, - start_index=1, category=category) + metric_name='g', start_index=1, + category=category) # set attributes self._radius = radius self._center = center diff --git a/src/sage/manifolds/differentiable/pseudo_riemannian.py b/src/sage/manifolds/differentiable/pseudo_riemannian.py index 7bdd3cc69b0..3b811883cd6 100644 --- a/src/sage/manifolds/differentiable/pseudo_riemannian.py +++ b/src/sage/manifolds/differentiable/pseudo_riemannian.py @@ -297,8 +297,8 @@ class PseudoRiemannianManifold(DifferentiableManifold): - ``n`` -- positive integer; dimension of the manifold - ``name`` -- string; name (symbol) given to the manifold - - ``metric_name`` -- (default: ``'g'``) string; name (symbol) given to the - metric + - ``metric_name`` -- (default: ``None``) string; name (symbol) given to the + metric; if ``None``, ``'g'`` is used - ``signature`` -- (default: ``None``) signature `S` of the metric as a single integer: `S = n_+ - n_-`, where `n_+` (resp. `n_-`) is the number of positive terms (resp. number of negative terms) in any @@ -412,8 +412,8 @@ class PseudoRiemannianManifold(DifferentiableManifold): -2 """ - def __init__(self, n, name, metric_name='g', signature=None, base_manifold=None, - diff_degree=infinity, latex_name=None, + def __init__(self, n, name, metric_name=None, signature=None, + base_manifold=None, diff_degree=infinity, latex_name=None, metric_latex_name=None, start_index=0, category=None, unique_tag=None): r""" @@ -450,7 +450,9 @@ def __init__(self, n, name, metric_name='g', signature=None, base_manifold=None, category=category) self._metric = None # to be initialized by metric() self._metric_signature = signature - if not isinstance(metric_name, str): + if metric_name is None: + metric_name = 'g' + elif not isinstance(metric_name, str): raise TypeError("{} is not a string".format(metric_name)) self._metric_name = metric_name if metric_latex_name is None: diff --git a/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py b/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py index 5e5869d929f..e3f15b5d8ef 100644 --- a/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +++ b/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py @@ -221,8 +221,8 @@ class PseudoRiemannianSubmanifold(PseudoRiemannianManifold, - ``ambient`` -- (default: ``None``) pseudo-Riemannian manifold `M` in which the submanifold is embedded (or immersed). If ``None``, it is set to ``self`` - - ``metric_name`` -- (default: ``'g'``) string; name (symbol) given to the - submanifold's metric + - ``metric_name`` -- (default: ``None``) string; name (symbol) given to the + metric; if ``None``, ``'gamma'`` is used - ``signature`` -- (default: ``None``) signature `S` of the metric as a single integer: `S = n_+ - n_-`, where `n_+` (resp. `n_-`) is the number of positive terms (resp. number of negative terms) in any @@ -236,7 +236,8 @@ class PseudoRiemannianSubmanifold(PseudoRiemannianManifold, - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote the submanifold; if none is provided, it is set to ``name`` - ``metric_latex_name`` -- (default: ``None``) string; LaTeX symbol to - denote the metric; if none is provided, it is set to ``metric_name`` + denote the metric; if none is provided, it is set to ``metric_name`` if + the latter is not ``None`` and to ``r'\gamma'`` otherwise - ``start_index`` -- (default: 0) integer; lower value of the range of indices used for "indexed objects" on the submanifold, e.g. coordinates in a chart @@ -300,10 +301,10 @@ class PseudoRiemannianSubmanifold(PseudoRiemannianManifold, :mod:`~sage.manifolds.differentiable.differentiable_submanifold` """ - def __init__(self, n, name, ambient=None, metric_name='g', signature=None, - base_manifold=None, diff_degree=infinity, latex_name=None, - metric_latex_name=None, start_index=0, category=None, - unique_tag=None): + def __init__(self, n, name, ambient=None, metric_name=None, + signature=None, base_manifold=None, diff_degree=infinity, + latex_name=None, metric_latex_name=None, start_index=0, + category=None, unique_tag=None): r""" Construct a pseudo-Riemannian submanifold. @@ -337,6 +338,9 @@ def __init__(self, n, name, ambient=None, metric_name='g', signature=None, 5-dimensional pseudo-Riemannian manifold M """ + if metric_name is None: + metric_name = 'gamma' + metric_latex_name = r'\gamma' PseudoRiemannianManifold.__init__(self, n, name=name, metric_name=metric_name, signature=signature, @@ -513,7 +517,7 @@ def first_fundamental_form(self): A sphere embedded in Euclidean space:: sage: M. = EuclideanSpace() - sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian") + sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian') sage: C. = N.chart(r'th:(0,pi):\theta ph:(-pi,pi):\phi') sage: r = var('r', domain='real') sage: assume(r>0) @@ -535,16 +539,105 @@ def first_fundamental_form(self): [ r^2 0] [ 0 r^2*sin(th)^2] + By default, the first fundamental form is named ``gamma``, but this + can be customized by means of the argument ``metric_name`` when + declaring the submanifold:: + + sage: P = Manifold(1, 'P', ambient=M, structure='Riemannian', + ....: metric_name='g') + sage: CP. = P.chart() + sage: F = P.diff_map(M, [t, 2*t, 3*t]) + sage: P.set_embedding(F) + sage: P.induced_metric() + Riemannian metric g on the 1-dimensional Riemannian submanifold P + embedded in the Euclidean space E^3 + sage: P.induced_metric().display() + g = 14 dt⊗dt + """ if self._first_fundamental_form is None: - self._first_fundamental_form = self.metric() + self._first_fundamental_form = super().metric() self._first_fundamental_form.set( self._immersion.pullback(self.ambient_metric())) - self._first_fundamental_form.set_name("gamma", r"\gamma") return self._first_fundamental_form induced_metric = first_fundamental_form + def metric(self, name=None, signature=None, latex_name=None, + dest_map=None): + r""" + Return the induced metric (first fundamental form) or define a new + metric tensor on the submanifold. + + A new (uninitialzed) metric is returned only if the argument ``name`` + is provided and differs from the metric name declared at the + construction of the submanifold; otherwise, the first fundamental + form is returned. + + INPUT: + + - ``name`` -- (default: ``None``) name given to the metric; if ``name`` + is ``None`` or equals the metric name declared when constructing + the submanifold, the first fundamental form is returned (see + :meth:`first_fundamental_form`) + - ``signature`` -- (default: ``None``; ignored if ``name`` is ``None``) + signature `S` of the metric as a single integer: `S = n_+ - n_-`, + where `n_+` (resp. `n_-`) is the number of positive terms (resp. + number of negative terms) in any diagonal writing of the metric + components; if ``signature`` is not provided, `S` is set to the + submanifold's dimension (Riemannian signature) + - ``latex_name`` -- (default: ``None``; ignored if ``name`` is ``None``) + LaTeX symbol to denote the metric; if ``None``, it is formed from + ``name`` + - ``dest_map`` -- (default: ``None``; ignored if ``name`` is ``None``) + instance of + class :class:`~sage.manifolds.differentiable.diff_map.DiffMap` + representing the destination map `\Phi:\ U \rightarrow M`, where `U` + is the current submanifold; if ``None``, the identity map is assumed + (case of a metric tensor field *on* `U`) + + OUTPUT: + + - instance of + :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric` + + EXAMPLES: + + Induced metric on a straight line of the Euclidean plane:: + + sage: M. = EuclideanSpace() + sage: N = Manifold(1, 'N', ambient=M, structure='Riemannian') + sage: CN. = N.chart() + sage: F = N.diff_map(M, [t, 2*t]) + sage: N.set_embedding(F) + sage: N.metric() + Riemannian metric gamma on the 1-dimensional Riemannian + submanifold N embedded in the Euclidean plane E^2 + sage: N.metric().display() + gamma = 5 dt⊗dt + + Setting the argument ``name`` to that declared while constructing + the submanifold (default = ``'gamma'``) yields the same result:: + + sage: N.metric(name='gamma') is N.metric() + True + + while using a different name allows one to define a new metric on the + submanifold:: + + sage: h = N.metric(name='h'); h + Riemannian metric h on the 1-dimensional Riemannian submanifold N + embedded in the Euclidean plane E^2 + sage: h[0, 0] = 1 # initialization + sage: h.display() + h = dt⊗dt + + """ + if name is None or name == self._metric_name: + return self.first_fundamental_form() + return super().metric(name=name, signature=signature, + latex_name=latex_name, dest_map=dest_map) + @cached_method def difft(self): r""" @@ -1162,7 +1255,7 @@ def second_fundamental_form(self): + " hypersurfaces") if self._second_fundamental_form is None: resu = self.vector_field_module().tensor((0, 2), name='K', - sym=[(0, 1)]) + sym=[(0, 1)]) if self._dim_foliation != 0: inverse_subs = {v: k for k, v in self._subs[0].items()} asff = self.ambient_second_fundamental_form() diff --git a/src/sage/manifolds/manifold.py b/src/sage/manifolds/manifold.py index 801ad12ab02..2645de657c9 100644 --- a/src/sage/manifolds/manifold.py +++ b/src/sage/manifolds/manifold.py @@ -3008,27 +3008,15 @@ def Manifold(dim, name, latex_name=None, field='real', structure='smooth', start_index=start_index, unique_tag=unique_tag()) elif structure in ['pseudo-Riemannian', 'Riemannian', 'Lorentzian','degenerate_metric']: - if 'diff_degree' in extra_kwds: - diff_degree = extra_kwds['diff_degree'] - else: - diff_degree = infinity - if 'metric_name' in extra_kwds: - metric_name = extra_kwds['metric_name'] - else: - metric_name = 'g' - if 'metric_latex_name' in extra_kwds: - metric_latex_name = extra_kwds['metric_latex_name'] - else: - metric_latex_name = None + diff_degree = extra_kwds.get('diff_degree', infinity) + metric_name = extra_kwds.get('metric_name', None) + metric_latex_name = extra_kwds.get('metric_latex_name', None) if structure == 'pseudo-Riemannian': - if 'signature' in extra_kwds: - signature = extra_kwds['signature'] - else: - signature = None + signature = extra_kwds.get('signature', None) elif structure == 'Riemannian': signature = dim elif structure == 'degenerate_metric': - signature = (0,dim-1,1) + signature = (0, dim-1, 1) elif structure == 'Lorentzian': if 'signature' in extra_kwds: signat = extra_kwds['signature']