{ "cells": [ { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "# Laplace-Beltrami operator\n", "\n", "This worksheet explores the issue raised by this [ask.sagemath question](https://ask.sagemath.org/question/37513/better-implementation-for-laplace-beltrami-operator/)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "'SageMath version 8.0.beta4, Release Date: 2017-04-27'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "version()" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "%display latex" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "Parallelism().set(nproc=1)" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "## Manifold and coordinate charts" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "M = Manifold(2*3,'R^6',field='real',start_index=1)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "m1, m2 = var('m1 m2', domain='real')" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "m_CM = m1+m2; mu1 = m1/m_CM; mu2 = m2/m_CM; mu = m1*m2/m_CM" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (R^6, (x1, y1, z1, x2, y2, z2))" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c_Cart. = M.chart()\n", "c_Cart" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "g = m1 dx1*dx1 + m1 dy1*dy1 + m1 dz1*dz1 + m2 dx2*dx2 + m2 dy2*dy2 + m2 dz2*dz2" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = M.riemannian_metric('g')\n", "g[1,1],g[2,2],g[3,3], g[4,4],g[5,5],g[6,6] = m1,m1,m1, m2,m2,m2; \n", "g.display()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (R^6, (X, Y, Z, x, y, z))" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c_CM. = M.chart()\n", "c_CM" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "X = m1*x1/(m1 + m2) + m2*x2/(m1 + m2)\n", "Y = m1*y1/(m1 + m2) + m2*y2/(m1 + m2)\n", "Z = m1*z1/(m1 + m2) + m2*z2/(m1 + m2)\n", "x = x1 - x2\n", "y = y1 - y2\n", "z = z1 - z2" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ch_Cart_CM = c_Cart.transition_map(c_CM, [mu1*x1+mu2*x2,mu1*y1+mu2*y2,mu1*z1+mu2*z2, x1-x2,y1-y2,z1-z2],\n", " restrictions2 = [x!=0, y!=0, z!=0])\n", "ch_Cart_CM.display()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "x1 = (X*(m1 + m2) + m2*x)/(m1 + m2)\n", "y1 = (Y*m1 + (Y + y)*m2)/(m1 + m2)\n", "z1 = (Z*m1 + (Z + z)*m2)/(m1 + m2)\n", "x2 = (X*(m1 + m2) - m1*x)/(m1 + m2)\n", "y2 = ((Y - y)*m1 + Y*m2)/(m1 + m2)\n", "z2 = ((Z - z)*m1 + Z*m2)/(m1 + m2)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ch_Cart_CM.inverse().display()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "M.set_default_chart(c_CM)\n", "M.set_default_frame(c_CM.frame())" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "## The scalar field $\\psi$" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "psiX: R^6 --> R\n", " (x1, y1, z1, x2, y2, z2) |--> Psi_X((m1*x1 + m2*x2)/(m1 + m2), (m1*y1 + m2*y2)/(m1 + m2), (m1*z1 + m2*z2)/(m1 + m2))\n", " (X, Y, Z, x, y, z) |--> Psi_X(X, Y, Z)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "psiX = M.scalar_field({c_CM: function('Psi_X')(X,Y,Z)}, name='psiX',\n", " latex_name='\\Psi_X')\n", "psiX.display()" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "psix: R^6 --> R\n", " (x1, y1, z1, x2, y2, z2) |--> psi_x(x1 - x2, y1 - y2, z1 - z2)\n", " (X, Y, Z, x, y, z) |--> psi_x(x, y, z)" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "psix = M.scalar_field({c_CM: function('psi_x')(x,y,z)}, name='psix',\n", " latex_name='\\psi_x')\n", "psix.display()" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "psi: R^6 --> R\n", " (x1, y1, z1, x2, y2, z2) |--> Psi_X((m1*x1 + m2*x2)/(m1 + m2), (m1*y1 + m2*y2)/(m1 + m2), (m1*z1 + m2*z2)/(m1 + m2))*psi_x(x1 - x2, y1 - y2, z1 - z2)\n", " (X, Y, Z, x, y, z) |--> Psi_X(X, Y, Z)*psi_x(x, y, z)" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "psi = psiX*psix\n", "psi.set_name('psi', latex_name='\\psi')\n", "psi.display()" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "## Laplace-Beltrami operator as $*\\mathrm{d}*\\mathrm{d}\\psi$" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 1.8 s, sys: 72 ms, total: 1.87 s\n", "Wall time: 1.81 s\n", "1-form dpsi on the 6-dimensional differentiable manifold R^6\n" ] } ], "source": [ "%time dpsi = psi.exterior_derivative()\n", "print(dpsi)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "dpsi = psi_x(x, y, z)*d(Psi_X)/dX dX + psi_x(x, y, z)*d(Psi_X)/dY dY + psi_x(x, y, z)*d(Psi_X)/dZ dZ + Psi_X(X, Y, Z)*d(psi_x)/dx dx + Psi_X(X, Y, Z)*d(psi_x)/dy dy + Psi_X(X, Y, Z)*d(psi_x)/dz dz" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dpsi.display()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 3min 21s, sys: 3.2 s, total: 3min 24s\n", "Wall time: 3min 23s\n", "5-form *dpsi on the 6-dimensional differentiable manifold R^6\n" ] } ], "source": [ "%time sdpsi = dpsi.hodge_dual(g)\n", "print(sdpsi)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 4.1 s, sys: 140 ms, total: 4.24 s\n", "Wall time: 4.09 s\n", "6-form d*dpsi on the 6-dimensional differentiable manifold R^6\n" ] } ], "source": [ "%time dsdpsi = sdpsi.exterior_derivative()\n", "print(dsdpsi)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "d*dpsi = (m1*m2*(d^2(Psi_X)/dX^2 + d^2(Psi_X)/dY^2 + d^2(Psi_X)/dZ^2)*psi_x(x, y, z) + (m1^2*Psi_X(X, Y, Z) + 2*m1*m2*Psi_X(X, Y, Z) + m2^2*Psi_X(X, Y, Z))*d^2(psi_x)/dx^2 + (m1^2*Psi_X(X, Y, Z) + 2*m1*m2*Psi_X(X, Y, Z) + m2^2*Psi_X(X, Y, Z))*d^2(psi_x)/dy^2 + (m1^2*Psi_X(X, Y, Z) + 2*m1*m2*Psi_X(X, Y, Z) + m2^2*Psi_X(X, Y, Z))*d^2(psi_x)/dz^2)*sqrt(m1)*sqrt(m2)/(m1 + m2) dX/\\dY/\\dZ/\\dx/\\dy/\\dz" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dsdpsi.display()" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 7min 11s, sys: 3.55 s, total: 7min 15s\n", "Wall time: 7min 11s\n", "Scalar field *d*dpsi on the 6-dimensional differentiable manifold R^6\n" ] } ], "source": [ "%time LBpsi = dsdpsi.hodge_dual(g)\n", "print(LBpsi)" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "## Laplace-Beltrami operator as $\\nabla_\\mu \\nabla^\\mu \\psi$" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Levi-Civita connection nabla_g associated with the Riemannian metric g on the 6-dimensional differentiable manifold R^6\n" ] } ], "source": [ "nabla = g.connection()\n", "print(nabla)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 12.7 s, sys: 248 ms, total: 13 s\n", "Wall time: 12.8 s\n" ] }, { "data": { "text/html": [ "" ], "text/plain": [ "Scalar field on the 6-dimensional differentiable manifold R^6" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%time LBpsi1 = nabla(nabla(psi).up(g)).trace()\n", "LBpsi1" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "(m1*m2*(d^2(Psi_X)/dX^2 + d^2(Psi_X)/dY^2 + d^2(Psi_X)/dZ^2)*psi_x(x, y, z) + (m1^2*Psi_X(X, Y, Z) + 2*m1*m2*Psi_X(X, Y, Z) + m2^2*Psi_X(X, Y, Z))*d^2(psi_x)/dx^2 + (m1^2*Psi_X(X, Y, Z) + 2*m1*m2*Psi_X(X, Y, Z) + m2^2*Psi_X(X, Y, Z))*d^2(psi_x)/dy^2 + (m1^2*Psi_X(X, Y, Z) + 2*m1*m2*Psi_X(X, Y, Z) + m2^2*Psi_X(X, Y, Z))*d^2(psi_x)/dz^2)/(m1^2*m2 + m1*m2^2)" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "LBpsi1.coord_function()" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Test:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "zero: R^6 --> R\n", " (x1, y1, z1, x2, y2, z2) |--> 0\n", " (X, Y, Z, x, y, z) |--> 0" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(LBpsi1 - LBpsi).display()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "SageMath 8.0.beta4", "language": "", "name": "sagemath" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.13" } }, "nbformat": 4, "nbformat_minor": 2 }