Ticket #19823: cotton.patch

File cotton.patch, 10.4 KB (added by pang, 5 years ago)

First draft

  • src/sage/manifolds/differentiable/metric.py

    diff --git a/src/sage/manifolds/differentiable/metric.py b/src/sage/manifolds/differentiable/metric.py
    index 6335dca..8ad1601 100644
    a b class PseudoRiemannianMetric(TensorField): 
    318318        True
    319319
    320320    """
     321    DERIVED_OBJECTS = ('_connection', '_ricci_scalar', '_weyl',
     322                       '_schouten', '_cotton', '_cotton_york')
     323
    321324    def __init__(self, vector_field_module, name, signature=None,
    322325                 latex_name=None):
    323326        r"""
    class PseudoRiemannianMetric(TensorField): 
    447450        self._inverse = self._vmodule.tensor((2,0), name=inv_name,
    448451                                             latex_name=inv_latex_name,
    449452                                             sym=(0,1))
    450         self._connection = None  # Levi-Civita connection (not set yet)
    451         self._ricci_scalar = None # Ricci scalar (not set yet)
    452         self._weyl = None # Weyl tensor (not set yet)
     453        for attr in self.DERIVED_OBJECTS:
     454            self.__setattr__(attr, None)
    453455        self._determinants = {} # determinants in various frames
    454456        self._sqrt_abs_dets = {} # sqrt(abs(det g)) in various frames
    455457        self._vol_forms = [] # volume form and associated tensors
    class PseudoRiemannianMetric(TensorField): 
    470472        # The inverse metric is cleared:
    471473        self._del_inverse()
    472474        # The connection, Ricci scalar and Weyl tensor are reset to None:
    473         self._connection = None
    474         self._ricci_scalar = None
    475         self._weyl = None
     475        # The Schouten, Cotton and Cotton-York tensors are reset to None:
     476        for attr in self.DERIVED_OBJECTS:
     477            self.__setattr__(attr, None)
    476478        # The dictionary of determinants over the various frames is cleared:
    477479        self._determinants.clear()
    478480        self._sqrt_abs_dets.clear()
    class PseudoRiemannianMetric(TensorField): 
    569571            resu._indic_signat = self._indic_signat
    570572            # Restrictions of derived quantities:
    571573            resu._inverse = self.inverse().restrict(subdomain)
    572             if self._connection is not None:
    573                 resu._connection = self._connection.restrict(subdomain)
    574             if self._ricci_scalar is not None:
    575                 resu._ricci_scalar = self._ricci_scalar.restrict(subdomain)
    576             if self._weyl is not None:
    577                 resu._weyl = self._weyl.restrict(subdomain)
     574            for attr in self.DERIVED_OBJECTS:
     575                derived = self.__getattribute__(attr)
     576                if derived is not None:
     577                    resu.__setattr__(attr, derived.restrict(subdomain))
    578578            if self._vol_forms != []:
    579579                for eps in self._vol_forms:
    580580                    resu._vol_forms.append(eps.restrict(subdomain))
    class PseudoRiemannianMetric(TensorField): 
    11891189            self._weyl.set_name(name=name, latex_name=latex_name)
    11901190        return self._weyl
    11911191
     1192    def schouten(self, name=None, latex_name=None):
     1193        r"""
     1194        Return the Schouten tensor associated with the metric.
     1195
     1196        The Schouten tensor is the tensor field `Sc` of type (0,2) defined
     1197        from the Ricci curvature tensor `Ric` and the scalar curvature `s`
     1198        and the metric `g` by
     1199
     1200        .. MATH::
     1201
     1202            Sc(u, v) = \frac{1}{n-2}\left(Ricci(u, v) + \frac{s}{2(n-1)}g(u,v)
     1203            \right)
     1204
     1205        for any vector fields `u` and `v`.
     1206
     1207        INPUT:
     1208
     1209        - ``name`` -- (default: ``None``) name given to the Schouten tensor;
     1210          if none, it is set to "Schouten(g)", where "g" is the metric's name
     1211        - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
     1212          Schouten tensor; if none, it is set to "\\mathrm{Schouten}(g)",
     1213          where "g" is the metric's name
     1214
     1215        OUTPUT:
     1216
     1217        - the Schouten tensor `Sc`, as an instance of
     1218          :class:`~sage.manifolds.differentiable.tensorfield.TensorField` of tensor
     1219          type (0,2) and symmetric
     1220
     1221        EXAMPLES:
     1222
     1223        Schouten tensor of the standard metric on the 2-sphere::
     1224
     1225            sage: M = Manifold(3, 'S^3', start_index=1)
     1226            sage: X.<x,y,z> = M.chart()
     1227            sage: g = M.riemannian_metric('g')
     1228            sage: #standard round sphere, stereographic projection
     1229            sage: f = 4/(1 + x^2 + y^2 + z^2)
     1230            sage: g[1,1], g[2,2], g[3,3] = f, f, f
     1231            sage: g.display() # standard metric on the 3-sphere of radius 1:
     1232            g = 4/(x^2 + y^2 + z^2 + 1) dx*dx + 4/(x^2 + y^2 + z^2 + 1) dy*dy +
     1233            4/(x^2 + y^2 + z^2 + 1) dz*dz
     1234            sage: g.schouten() # long time
     1235            Field of symmetric bilinear forms Schouten(g) on the 3-dimensional
     1236            differentiable manifold S^3
     1237            sage: g.schouten()[1,2] # long time
     1238            -x*y/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1)
     1239
     1240        """
     1241        n = self._ambient_domain.dimension()
     1242        if n < 3:
     1243            raise ValueError("the Schouten tensor is only defined for a " +
     1244                             "manifold of dimension >= 3")
     1245        if self._schouten is None:
     1246            s = (1/(n-2))*self.ricci() - (self.ricci_scalar()/(2*(n-1)*(n-2)))*self
     1247            name = name or 'Schouten(' + self._name + ')'
     1248            latex_name = latex_name or r'\mathrm{Schouten}(' + self._latex_name + ')'
     1249            s.set_name(name=name, latex_name=latex_name)
     1250            self._schouten = s
     1251        return self._schouten
     1252
     1253    def cotton(self, name=None, latex_name=None):
     1254        r"""
     1255        Return the Cotton conformal tensor associated with the metric.
     1256        The tensor has type (0,3) and is defined in terms of the Schouten
     1257        tensor `S`
     1258
     1259        .. MATH::
     1260
     1261            C_{ijk}=\left(\nabla_i S\right)_{jk}-\left(\nabla_j S\right)_{ik}
     1262
     1263        INPUT:
     1264
     1265        - ``name`` -- (default: ``None``) name given to the Cotton conformal
     1266          tensor; if ``None``, it is set to "Cot(g)", where "g" is the metric's
     1267          name
     1268        - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
     1269          Cotton conformal tensor; if ``None``, it is set to "\\mathrm{Cot}(g)",
     1270          where "g" is the metric's name
     1271
     1272        OUTPUT:
     1273
     1274        - the Cotton conformal tensor `Cot`, as an instance of
     1275          :class:`~sage.manifolds.differentiable.tensorfield.TensorField`
     1276
     1277        EXAMPLES:
     1278
     1279        Checking that the Cotton tensor identically vanishes on a conformally flat
     1280        3-dimensional manifold, for instance the hyperbolic space `H^3`::
     1281
     1282            sage: M = Manifold(3, 'H^3', start_index=1)
     1283            sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
     1284            sage: X.<rh,th,ph> = U.chart(r'rh:(0,+oo):\rho th:(0,pi):\theta  ph:(0,2*pi):\phi')
     1285            sage: g = U.metric('g')
     1286            sage: b = var('b')
     1287            sage: g[1,1], g[2,2], g[3,3] = b^2, (b*sinh(rh))^2, (b*sinh(rh)*sin(th))^2
     1288            sage: g.display()  # standard metric on H^3:
     1289            g = b^2 drh*drh + b^2*sinh(rh)^2 dth*dth
     1290             + b^2*sin(th)^2*sinh(rh)^2 dph*dph
     1291            sage: Cot = g.cotton() ; Cot # long time
     1292            Tensor field Cot(g) of type (0,3) on the Open subset U of the
     1293             3-dimensional differentiable manifold H^3
     1294            sage: Cot == 0 # long time
     1295            True
     1296
     1297        """
     1298        n = self._ambient_domain.dimension()
     1299        if n < 3:
     1300            raise ValueError("the Cotton tensor is only defined for a " +
     1301                             "manifold of dimension >= 3")
     1302        if self._cotton is None:
     1303            nabla = self.connection()
     1304            s = self.schouten()
     1305            cot = nabla(s).antisymmetrize(0,2)
     1306            name = name or 'Cot(' + self._name + ')'
     1307            latex_name = latex_name or r'\mathrm{Cot}(' + self._latex_name + ')'
     1308            cot.set_name(name=name, latex_name=latex_name)
     1309            self._cotton = cot
     1310        return self._cotton
     1311
     1312    def cotton_york(self, name=None, latex_name=None):
     1313        r"""
     1314        Return the Cotton-York conformal tensor associated with the metric.
     1315        The tensor has type (0,2) and is only defined for manifolds of
     1316        dimension 3. It is defined in terms of the Cotton tensor `C` or the
     1317        Schouten tensor `S`
     1318
     1319        .. MATH::
     1320
     1321            CY_{ij} = \frac{1}{2}C_{kli} g_{jm} \frac{\epsilon^{klm}}{\sqrt{\det g}}
     1322            =g_{jm}\left(\nabla_k S \right)_{li}\frac{\epsilon^{klm}}{\sqrt{\det{g}}}
     1323
     1324        INPUT:
     1325
     1326        - ``name`` -- (default: ``None``) name given to the Cotton-York
     1327          tensor; if ``None``, it is set to "CY(g)", where "g" is the metric's
     1328          name
     1329        - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
     1330          Cotton-York tensor; if ``None``, it is set to "\\mathrm{CY}(g)",
     1331          where "g" is the metric's name
     1332
     1333        OUTPUT:
     1334
     1335        - the Cotton-York conformal tensor `CY`, as an instance of
     1336          :class:`~sage.manifolds.differentiable.tensorfield.TensorField`
     1337
     1338        EXAMPLES:
     1339
     1340        Checking that the Cotton-York tensor has determinant zero for a product
     1341        if :math:`\mathbb{R}` with a surface::
     1342
     1343            sage: M = Manifold(3, 'RxS', start_index=1)
     1344            sage: X.<x,y,z> = M.chart()
     1345            sage: g = M.riemannian_metric('g')
     1346            sage: _f = function('F', y, z)
     1347            sage: f = X.domain().scalar_field(_f)
     1348            sage: g[1,1], g[2,2], g[3,3] = 1, f, f
     1349            sage: g.display()
     1350            g = dx*dx + F(y, z) dy*dy + F(y, z) dz*dz
     1351            sage: CY = g.cotton_york() ; CY # long time
     1352            Tensor field of type (0,2) on the 3-dimensional differentiable
     1353             manifold RxS
     1354            sage: det(CY[:]) # long time
     1355            0
     1356
     1357        """
     1358        n = self._ambient_domain.dimension()
     1359        if n < 3:
     1360            raise ValueError("the Cotton-York tensor is only defined for a " +
     1361                             "manifold of dimension 3")
     1362        if self._cotton_york is None:
     1363            cot = self.cotton()
     1364            eps = self.volume_form(2)
     1365            cy = -cot.contract(0,2,eps,0,1)
     1366            name = name or 'CY(' + self._name + ')'
     1367            latex_name = latex_name or r'\mathrm{CY}(' + self._latex_name + ')'
     1368            cot.set_name(name=name, latex_name=latex_name)
     1369            self._cotton_york = cy
     1370        return self._cotton_york
     1371
    11921372    def determinant(self, frame=None):
    11931373        r"""
    11941374        Determinant of the metric components in the specified frame.