{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Smooth manifolds, vector fields and tensor fields\n", "\n", "This notebook accompanies the lecture\n", "[Symbolic tensor calculus on manifolds](http://sagemanifolds.obspm.fr/jncf2018/) at JNCF 2018.\n", "\n", "Click [here](https://raw.githubusercontent.com/sagemanifolds/SageManifolds/master/Worksheets/JNCF2018/jncf18_vector.ipynb) to download the notebook file (ipynb format). To run it, you must start SageMath with the Jupyter Notebook server, via the command sage -n jupyter" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%display latex" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us restore the 2-sphere manifold constructed in the [preceeding worksheet](http://nbviewer.jupyter.org/github/sagemanifolds/SageManifolds/blob/master/Worksheets/JNCF2018/jncf18_scalar.ipynb):" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "[Chart (U, (x, y)),\n", " Chart (V, (xp, yp)),\n", " Chart (W, (x, y)),\n", " Chart (W, (xp, yp))]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "M = Manifold(2, 'M')\n", "U = M.open_subset('U')\n", "XU. = U.chart()\n", "V = M.open_subset('V')\n", "XV. = V.chart(\"xp:x' yp:y'\")\n", "M.declare_union(U,V)\n", "XU_to_XV = XU.transition_map(XV, \n", " (x/(x^2+y^2), y/(x^2+y^2)), \n", " intersection_name='W',\n", " restrictions1= x^2+y^2!=0, \n", " restrictions2= xp^2+yp^2!=0)\n", "XV_to_XU = XU_to_XV.inverse()\n", "M.atlas()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We also reconstruct the point $p$:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point p on the 2-dimensional differentiable manifold M\n" ] } ], "source": [ "p = U((1,2), chart=XU, name='p')\n", "print(p)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and the embedding $\\mathbb{S}^2 \\to \\mathbb{R}^3$:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Phi: M --> R^3\n", "on U: (x, y) |--> (X, Y, Z) = (2*x/(x^2 + y^2 + 1), 2*y/(x^2 + y^2 + 1), (x^2 + y^2 - 1)/(x^2 + y^2 + 1))\n", "on V: (xp, yp) |--> (X, Y, Z) = (2*xp/(xp^2 + yp^2 + 1), 2*yp/(xp^2 + yp^2 + 1), -(xp^2 + yp^2 - 1)/(xp^2 + yp^2 + 1))" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R3 = Manifold(3, 'R^3', r'\\mathbb{R}^3')\n", "XR3. = R3.chart()\n", "Phi = M.diff_map(R3, {(XU, XR3): \n", " [2*x/(1+x^2+y^2), 2*y/(1+x^2+y^2),\n", " (x^2+y^2-1)/(1+x^2+y^2)],\n", " (XV, XR3): \n", " [2*xp/(1+xp^2+yp^2), 2*yp/(1+xp^2+yp^2),\n", " (1-xp^2-yp^2)/(1+xp^2+yp^2)]},\n", " name='Phi', latex_name=r'\\Phi')\n", "Phi.display()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "graph = XU.plot(chart=XR3, mapping=Phi, number_values=25, \n", " label_axes=False) + \\\n", " XV.plot(chart=XR3, mapping=Phi, number_values=25, \n", " color='green', label_axes=False) + \\\n", " p.plot(chart=XR3, mapping=Phi, label_offset=0.05)\n", "show(graph, viewer='threejs', online=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally we reconstruct the scalar field $f$:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "f: M --> R\n", "on U: (x, y) |--> 1/(x^2 + y^2 + 1)\n", "on V: (xp, yp) |--> (xp^2 + yp^2)/(xp^2 + yp^2 + 1)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f = M.scalar_field({XU: 1/(1+x^2+y^2), XV: (xp^2+yp^2)/(1+xp^2+yp^2)},\n", " name='f')\n", "f.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and assign the Python variable CM to the algebra of scalar fields:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Algebra of differentiable scalar fields on the 2-dimensional differentiable manifold M" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "CM = M.scalar_field_algebra()\n", "CM" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tangent vectors\n", "\n", "The tangent space at the point $p$ introduced above is generated by" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Tangent space at Point p on the 2-dimensional differentiable manifold M" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Tp = M.tangent_space(p)\n", "Tp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is a vector space over $\\mathbb{R}$, which is represented by Sage's Symbolic Ring:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Category of finite dimensional vector spaces over Symbolic Ring\n" ] } ], "source": [ "print(Tp.category())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The dimension of $T_p M$ is the same as that of $M$:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "2" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dim(Tp)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tangent spaces are implemented as a class inherited from TangentSpace via the category framework:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(Tp)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The class TangentSpace actually inherits from the generic class\n", "FiniteRankFreeModule, which, in SageMath, is devoted to free modules of finite rank\n", "without any distinguished basis:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "isinstance(Tp, FiniteRankFreeModule)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Two bases of $T_p M$ are already available: those generated by the derivations\n", "at $p$ along the coordinates of charts XU and XV respectively:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "[Basis (d/dx,d/dy) on the Tangent space at Point p on the 2-dimensional differentiable manifold M,\n", " Basis (d/dxp,d/dyp) on the Tangent space at Point p on the 2-dimensional differentiable manifold M]" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Tp.bases()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "None of these bases is distinguished, but one if the default one, which\n", "simply means that it is the basis to be considered if the basis argument\n", "is skipped in some methods:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Basis (d/dx,d/dy) on the Tangent space at Point p on the 2-dimensional differentiable manifold M" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Tp.default_basis()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A tangent vector is created as an element of the tangent space by the\n", "standard SageMath procedure\n", "new\\_element = parent(...), where ...\n", "stands for some material sufficient to construct the element:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tangent vector v at Point p on the 2-dimensional differentiable manifold M\n" ] } ], "source": [ "vp = Tp((-3, 2), name='v')\n", "print(vp)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since the basis is not specified, the pair $(-3,2)$ refers to components\n", "with respect to the default basis:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "v = -3 d/dx + 2 d/dy" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vp.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have of course" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Tangent space at Point p on the 2-dimensional differentiable manifold M" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vp.parent()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vp in Tp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As other manifold objects, tangent vectors have some plotting capabilities:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "graph += vp.plot(chart=XR3, mapping=Phi, scale=0.5, color='gold')\n", "show(graph, viewer='threejs', online=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The main attribute of the object vp representing the vector $v$ is the dictionary _components, which stores the components of $v$ in various bases of $T_p M$:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "{Basis (d/dx,d/dy) on the Tangent space at Point p on the 2-dimensional differentiable manifold M: 1-index components w.r.t. Basis (d/dx,d/dy) on the Tangent space at Point p on the 2-dimensional differentiable manifold M}" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vp._components" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see above, the keys of the dictionary _components are the bases of $T_p M$, while the values belongs to the class [Components](http://doc.sagemath.org/html/en/reference/tensor_free_modules/sage/tensor/modules/comp.html) devoted to store ring elements indexed by integers or tuples of integers:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "1-index components w.r.t. Basis (d/dx,d/dy) on the Tangent space at Point p on the 2-dimensional differentiable manifold M" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vpc = vp._components[Tp.default_basis()]\n", "vpc" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(vpc)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The components themselves are stored in the dictionary _comp of the Components object, with the indices as keys:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "{(0,): -3, (1,): 2}" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vpc._comp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Module of vector fields\n", "\n", "The $C^\\infty(M)$-module of vector fields on $M$, $\\mathfrak{X}(M)$, is obtained as" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Module X(M) of vector fields on the 2-dimensional differentiable manifold M" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "YM = M.vector_field_module()\n", "YM" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Category of modules over Algebra of differentiable scalar fields on the 2-dimensional differentiable manifold M" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "YM.category()" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "YM.base_ring() is CM" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$\\mathfrak{X}(M)$ is not a free module (at least its SageMath implementation does not\n", "belong to the class FiniteRankFreeModule):" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/html": [ "