{
"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
}