Skip to content

Instantly share code, notes, and snippets.

@miguelgondu
Last active May 25, 2018 18:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miguelgondu/55b1ee946153efaf3541da8660489639 to your computer and use it in GitHub Desktop.
Save miguelgondu/55b1ee946153efaf3541da8660489639 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Metrics and differential geometry"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import generalrepytivity as gr\n",
"import sympy\n",
"sympy.init_printing(use_latex=True)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from pprint import pprint"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Summary of last tutorial "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[In the first tutorial](https://gist.github.com/miguelgondu/0e8ba345f25b6c9ab007084e472202c8) we got to know about the `Tensor` object in `generalrelativity`. It can be created by specifying a basis of sympy symbols, a type $(p,q)$ and a dict of values. In this one we use metrics (that is, $(0,2)$-tensors that can be represented by a non-degenerate symmetric matrix) to raise and lower indices, and we also talk about index contraction."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# The (0,2)-Tensor to matrix equivalence. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`generalrelativity` has two functions: one gets an $(0,2)$-tensor from a matrix and the other one gets a matrix from an $(0,2)$-tensor. Their syntaxes are:\n",
"\n",
"```python\n",
"new_tensor = gr.get_tensor_from_matrix(matrix, basis)\n",
"new_matrix = gr.get_matrix_from_tensor(tensor)\n",
"```\n",
"\n",
"For example"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAIgAAABkCAMAAABq4oiZAAAAP1BMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFBd4eAAAAFHRSTlMAMquZdlQQQO0wRM3d72aJIrt8bL89SzcAAAAJcEhZcwAADsQAAA7EAZUrDhsAAANwSURBVGgF7Zttk6IwEIQjIO75gnqX//9bj0BFk77J9KRwXa8qfAmhJzOPAyLtrm7nl61zP7Sd1/rO7Xw/zNv+hzjcFKp3PoDsforhWXfaAjL21+lafhFVMgPZX8YnNe6d5rM5nm94OM6rZBVk7PrOl0GmSyh5PcXCMNbJKsiceVBA7sv7bF+KqJO3gPgF5OgLb7c6eQPI6PtwMo5+gHOyTivlDSA3fw0ld+vwD0ylvAlk6UgZpErOQMbT+bGd1vuDcrFW9h5ahqszEIgNUwXErVfjXr9YrfIWkPs9oE7Ft2+VvAVkvWP1+g3NKm8Bcedwi78UP2yqZB2k7y7+1E3hDEjbeJ0/voscrkrWQaTq33SsgWBjW0daR7ADOG/XSOsIdgDn8jVCrBEmKcxJllyWQYg1ehZ+nf8SQYg1ihwv9V8iCLFGEWQetSdJkgVkEYRYIyMIyQKyBIIP2Elh3FU6QrKgLIEQa5TCKCAkC8oyiGqNzCBqlttqWB/2TALBrqWVYV/pCMmCcgA5+EOenzinJFgBqfRfv6WvrohzMoKQLCBLp8YR52QEIVlAFkGYc3qSaKeGZcn9lwxCrFEEeaX/kkFipTeODQSb3TrSOoIdwHm4Rsah/H07xn/b/DZ/bfz//73mle358Ldv7n2KL9wYVlifr5Y7YjRYNKzCf4kgRoNFwur8lwgC3qfQWsfDtMcVWC2CgPcpgfAwDQRWSyD4gF0AMYQpILhaAkHvUwAxhCkguFoGUa1R5EKLFI8nowqSF5FAsGtJ5nTXEKaA4OoAcvj6lRZwzBrFYO7DFBAs8udL+NAD7xML48jDNBBYLZ0aq8ECi4Sc81wDgdUiCLNGsWRukeLRZNRAoIgMYjRYJKzKf8kgyYt6124DwU63jrSOYAdw3q6R1hHsAM7layT3PrjmMSdhRH6kWXZkEOqc1iQkjMjOpf5LBCHOKb4UEkZk8F8iCHifWBhHEkbkOVv6uCKCgPdBgDgnYUQ2gOADdiwMIwkjckjGOoLeBwDilIQR2QaSe59YGUZisIhsATE0NaQhYUS2gKD3CWukjRgsIs8Z2TXiwPtIEOEYCSOyBQS8TwmEhBHZAgLepwTCwqr8l3hDY//cF8mIwSJy7r9kkFjpjWMDwWa3jnx4Rz7kF0dj+MXPMByxW++aL784Ggb3F9m+Q9pcNG9pAAAAAElFTkSuQmCC\n",
"text/latex": [
"$$\\left[\\begin{matrix}-1 & 0 & 0 & 0\\\\0 & 1 & 0 & 0\\\\0 & 0 & 1 & 0\\\\0 & 0 & 0 & 1\\end{matrix}\\right]$$"
],
"text/plain": [
"⎡-1 0 0 0⎤\n",
"⎢ ⎥\n",
"⎢0 1 0 0⎥\n",
"⎢ ⎥\n",
"⎢0 0 1 0⎥\n",
"⎢ ⎥\n",
"⎣0 0 0 1⎦"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"A = sympy.diag(-1, 1, 1, 1)\n",
"A"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$(1)de_2 \\otimes de_2 + (1)de_1 \\otimes de_1 + (-1)de_0 \\otimes de_0 + (1)de_3 \\otimes de_3$"
],
"text/plain": [
"(1)e_2* \\otimes e_2* + (1)e_1* \\otimes e_1* + (-1)e_0* \\otimes e_0* + (1)e_3* \\otimes e_3*"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"e0, e1, e2, e3 = sympy.symbols('e_0 e_1 e_2 e_3')\n",
"basis = [e0, e1, e2, e3]\n",
"T = gr.get_tensor_from_matrix(A, basis)\n",
"T"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAIgAAABkCAMAAABq4oiZAAAAP1BMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFBd4eAAAAFHRSTlMAMquZdlQQQO0wRM3d72aJIrt8bL89SzcAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAPeSURBVGgF7ZvhlqIwDIURkJlVFN3l/Z91KXjr9k7IpcuOM3tO+RNK0uQjoHK1Vodx3urqi7Z+qV9Vh7Fpp+34RRzVNVSvxwBy+CqGZ93rHpCuGa7D+klkuRXI8dI9qXnvPF3Nrr/xYYyz3C5IVzf1uA5yvYSSwxmFyea5XZApc+uA3OfX2XEtIs+9B2ScQU7jysstz70DpBubcDFOY0vXZBlmuneA3MYhlDws5gNMpnsXyNyRdZAsdwLSnfu4nZf3B+dmzew9tYxnJyAUG4YOSLXcjUf/Zt3q3gNyvwfU6+rLN8u9B2R5x2r8N7St7j0gVR/e4i+rHzZZbh+kqS/jub6GK2Bt3TB9fK9yVFluH8Sq/knHCgg3tnSkdIQ7wONyj5SOcAd4bN8jQhohycYwhJNNZ9sgQhohowzLkGcmiJBG4BBhefLMBBHSCCA6zHvQpNkmiJBGANFhHgjNtkD4ARuFyW4Ic0B4tgUipBF4NoQ5IDzbBnGl0RNEhrkg6WwLhLuGymQ3hDkgPDuAvI1vaQ2hnBCswxwQlmc/ra+uhHICiA7zQGi2dWkqoZwAosM8EJptgijlBBKhoHzlTEVsECGNACLCsuSZDYJKL7QFhJtdOlI6wh3gcbhHunb9+3aO/7Txbfra+P//veZftuebv3xT7fO3Jy6ypG67I1I5gS1DQWFKtGkRE0QoJ6TKU1CYBUtFTBDSPphqWO/JR2QhtwlC2scAwCEPRGQhtwXCD9ioalgHRGRhtwXC2scAwCEHRGRhtw2Sah9UNawL4ma5Lb8Ixt+/LBDumgGAQw6IyMLuAPL2/gOJF6uVE+IdEFZQmAJLRX69Gx96pH0w1bAeiMhCbuvSbBVYE5gHQgqKT4PcJghpH07xx9gDUVlSeWaDCOUEkiwFhUnRpkVskBj8up0Cwr0uHSkd4Q7wuNwjpSPcAR7b90iqfXhOHIsw4b41zf0e11rYIKn2iYV5R4T57i6sYhvG0yOpCULah+tjLMKEu56/C7nMywynjCYIaR8UZivChPvSh3w1lrCaIKR9GABjESbc53mRlAvCD9goTFaECfcjWY81W1ZHWPsQAIYiTLiXLKe4vtAGcaXRE8QNYwWFaYnt44pvC2RbUysRJtwzTzOfyrxrgShphHMiiYTDsMI9hbVPjpWXr7+4D5VIIuEwrHBX1TFw3B5Lps2OkPZBZrYiTLirw9yP1gNR0ghEqUTC0Wh9960fhqGp57e1aYrZEbW4D6VSiYSj0fru8/JHBR8k5nrdjt2R19WPlQpIbMVjp3TE7sg3+cdRF/7x07Z4emTWTx/P/zhq2+o3vJJEwZt/S5MAAAAASUVORK5CYII=\n",
"text/latex": [
"$$\\left[\\begin{matrix}-1 & 0 & 0 & 0\\\\0 & 0 & 1 & 0\\\\0 & 1 & 0 & 0\\\\0 & 0 & 0 & 2\\end{matrix}\\right]$$"
],
"text/plain": [
"⎡-1 0 0 0⎤\n",
"⎢ ⎥\n",
"⎢0 0 1 0⎥\n",
"⎢ ⎥\n",
"⎢0 1 0 0⎥\n",
"⎢ ⎥\n",
"⎣0 0 0 2⎦"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dict_of_values = {\n",
" (0,0): -1,\n",
" (1,2): 1,\n",
" (2,1): 1,\n",
" (3,3): 2\n",
"}\n",
"S = gr.Tensor(basis, (0, 2), dict_of_values)\n",
"S_matrix = gr.get_matrix_from_tensor(S)\n",
"S_matrix"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Raising and lowering indices using a metric, contracting indices"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A very common operation in general relativity is **raising and lowering indices** (with respect to a metric) and **contracting indices**. the syntaxs of those functions are\n",
"\n",
"```python\n",
"new_tensor = gr.raise_index(old_tensor, metric, index_to_be_raised)\n",
"new_tensor = gr.lower_index(old_tensor, metric, index_to_be_lowered)\n",
"new_tensor = gr.contract_indices(old_tensor, upper_index, lower_index)\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These functions are mostly used internally for calculating the derived tensors from the Riemann tensor (i.e. Ricci tensor, scalar curvature, Einstein tensor)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# The Levi-Civita connection of a metric "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Once we have a metric $g$, `generalrelativiy` can calculate the Christoffel symbols of the Levi-Civita connection with the function `gr.get_christoffel_symbols_from_metric`, which returns a $(1,2)$ tensor."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As a practical example, consider the metric Gödel proposed:\n",
"\n",
"$$ g = a^2(dx_0\\otimes dx_0 - dx_1\\otimes dx_1 + (e^{2x_1}/2)dx_2\\otimes dx_2 - dx_3\\otimes dx_3 + e^{x_1}dx_0\\otimes dx_2 + e^{x_1}dx_2 \\otimes dx_0) $$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's calculate the Christoffel symbols of the Levi-Civita connection associated with this metric:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$(- a^{2})dx_1 \\otimes dx_1 + (a^{2})dx_0 \\otimes dx_0 + (a^{2} e^{x_{1}})dx_0 \\otimes dx_2 + (0.5 a^{2} e^{2 x_{1}})dx_2 \\otimes dx_2 + (a^{2} e^{x_{1}})dx_2 \\otimes dx_0 + (- a^{2})dx_3 \\otimes dx_3$"
],
"text/plain": [
"(-a**2)x_1* \\otimes x_1* + (a**2)x_0* \\otimes x_0* + (a**2*exp(x_1))x_0* \\otimes x_2* + (0.5*a**2*exp(2*x_1))x_2* \\otimes x_2* + (a**2*exp(x_1))x_2* \\otimes x_0* + (-a**2)x_3* \\otimes x_3*"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a, x0, x1, x2, x3 = sympy.symbols('a x_0 x_1 x_2 x_3')\n",
"basis = [x0, x1, x2, x3]\n",
"e = sympy.exp(1)\n",
"values = {\n",
" (0,0): a**2,\n",
" (1,1): -a**2,\n",
" (2,2): (1/2) * a**2 * e**(2*x1),\n",
" (3,3): -a**2,\n",
" (0,2): a**2*e**x1,\n",
" (2,0): a**2*e**x1,\n",
"}\n",
"g = gr.Tensor(basis, (0, 2), values)\n",
"g"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's take a look at the matrix representation from $g$ and its respective inverse:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/latex": [
"$$\\left[\\begin{matrix}a^{2} & 0 & a^{2} e^{x_{1}} & 0\\\\0 & - a^{2} & 0 & 0\\\\a^{2} e^{x_{1}} & 0 & 0.5 a^{2} e^{2 x_{1}} & 0\\\\0 & 0 & 0 & - a^{2}\\end{matrix}\\right]$$"
],
"text/plain": [
"⎡ 2 2 x₁ ⎤\n",
"⎢ a 0 a ⋅ℯ 0 ⎥\n",
"⎢ ⎥\n",
"⎢ 2 ⎥\n",
"⎢ 0 -a 0 0 ⎥\n",
"⎢ ⎥\n",
"⎢ 2 x₁ 2 2⋅x₁ ⎥\n",
"⎢a ⋅ℯ 0 0.5⋅a ⋅ℯ 0 ⎥\n",
"⎢ ⎥\n",
"⎢ 2⎥\n",
"⎣ 0 0 0 -a ⎦"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"g_matrix = gr.get_matrix_from_tensor(g)\n",
"g_matrix"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/latex": [
"$$\\left[\\begin{matrix}- \\frac{1.0}{a^{2}} & 0 & \\frac{2.0}{a^{2}} e^{- x_{1}} & 0\\\\0 & - \\frac{1}{a^{2}} & 0 & 0\\\\\\frac{2.0}{a^{2}} e^{- x_{1}} & 0 & - \\frac{2.0}{a^{2}} e^{- 2 x_{1}} & 0\\\\0 & 0 & 0 & - \\frac{1}{a^{2}}\\end{matrix}\\right]$$"
],
"text/plain": [
"⎡ -x₁ ⎤\n",
"⎢ -1.0 2.0⋅ℯ ⎥\n",
"⎢ ───── 0 ──────── 0 ⎥\n",
"⎢ 2 2 ⎥\n",
"⎢ a a ⎥\n",
"⎢ ⎥\n",
"⎢ -1 ⎥\n",
"⎢ 0 ─── 0 0 ⎥\n",
"⎢ 2 ⎥\n",
"⎢ a ⎥\n",
"⎢ ⎥\n",
"⎢ -x₁ -2⋅x₁ ⎥\n",
"⎢2.0⋅ℯ -2.0⋅ℯ ⎥\n",
"⎢──────── 0 ──────────── 0 ⎥\n",
"⎢ 2 2 ⎥\n",
"⎢ a a ⎥\n",
"⎢ ⎥\n",
"⎢ -1 ⎥\n",
"⎢ 0 0 0 ───⎥\n",
"⎢ 2⎥\n",
"⎣ a ⎦"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"g_matrix.inv()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can calculate the Christoffel symbols using the function mentioned above:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{((0,), (0, 1)): 1.00000000000000,\n",
" ((0,), (1, 0)): 1.00000000000000,\n",
" ((0,), (1, 2)): 0.5*exp(x_1),\n",
" ((0,), (2, 1)): 0.5*exp(x_1),\n",
" ((1,), (0, 2)): 0.5*exp(x_1),\n",
" ((1,), (2, 0)): 0.5*exp(x_1),\n",
" ((1,), (2, 2)): 0.5*exp(2*x_1),\n",
" ((2,), (0, 1)): -1.0*exp(-x_1),\n",
" ((2,), (1, 0)): -1.0*exp(-x_1)}\n"
]
}
],
"source": [
"cs = gr.get_chrisoffel_symbols_from_metric(g)\n",
"pprint(cs.values)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All of which coincide with what's mentioned in the original article. Note that Christoffel symbols are created as `Tensor` objects, although they aren't tensors, theoretically speaking. This is because it's easier to deal with them as `Tensor` objects than it is to create a whole new class for holding them."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Riemann tensor and friends "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`generalrelativity` has functions that allow you to calculate the Riemann, Ricci and Einstein tensors as well as the scalar curvature. Their syntax goes as follows:\n",
"```python\n",
"Riem = gr.get_Riemann_tensor(Christoffel_symbols)\n",
"Ric = gr.get_Ricci_tensor(Christoffel_symbols)\n",
"R = gr.get_scalar_curvature(Christoffel_symbols, metric)\n",
"G = gr.get_Einstein_tensor(Christoffel_symbols, metric)\n",
"```\n",
"\n",
"One can also pass the `Riem` tensor in `Ric` (in order to avoid redundant calculations, for example)\n",
"\n",
"If it seems redundant to put the `metric` as an argument in both `R` and `G` is becuase it theoretically is: the `Christoffel_symbols` should hold the information about the `metric` in them, but because they are implemented as tensors, they are not (yet) designed to hold that information, so one must necessarily provide it as an argument.\n",
"\n",
"\n",
"Using the same example as before (i.e. the Gödel metric), let's calculate each and every one of them:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Riemann tensor "
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{((0,), (0, 0, 2)): 0.5*exp(x_1),\n",
" ((0,), (0, 2, 0)): -0.5*exp(x_1),\n",
" ((0,), (1, 0, 1)): -0.500000000000000,\n",
" ((0,), (1, 1, 0)): 0.500000000000000,\n",
" ((0,), (1, 1, 2)): 1.0*exp(x_1),\n",
" ((0,), (1, 2, 1)): -1.0*exp(x_1),\n",
" ((0,), (2, 0, 2)): 0.25*exp(2*x_1),\n",
" ((0,), (2, 2, 0)): -0.25*exp(2*x_1),\n",
" ((1,), (0, 0, 1)): -0.500000000000000,\n",
" ((1,), (0, 1, 0)): 0.500000000000000,\n",
" ((1,), (0, 1, 2)): 0.5*exp(x_1),\n",
" ((1,), (0, 2, 1)): -0.5*exp(x_1),\n",
" ((1,), (2, 0, 1)): -0.5*exp(x_1),\n",
" ((1,), (2, 1, 0)): 0.5*exp(x_1),\n",
" ((1,), (2, 1, 2)): 0.75*exp(2*x_1),\n",
" ((1,), (2, 2, 1)): -0.75*exp(2*x_1),\n",
" ((2,), (0, 0, 2)): -0.500000000000000,\n",
" ((2,), (0, 2, 0)): 0.500000000000000,\n",
" ((2,), (1, 1, 2)): -0.500000000000000,\n",
" ((2,), (1, 2, 1)): 0.500000000000000,\n",
" ((2,), (2, 0, 2)): -0.5*exp(x_1),\n",
" ((2,), (2, 2, 0)): 0.5*exp(x_1)}\n"
]
}
],
"source": [
"Riem = gr.get_Riemann_tensor(cs)\n",
"pprint(Riem.values)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Ricci tensor "
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{((), (0, 0)): 1.00000000000000,\n",
" ((), (0, 2)): 1.0*exp(x_1),\n",
" ((), (2, 0)): 1.0*exp(x_1),\n",
" ((), (2, 2)): 1.0*exp(2*x_1)}\n"
]
}
],
"source": [
"Ric = gr.get_Ricci_tensor(cs, Riem)\n",
"pprint(Ric.values)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{((), (0, 0)): 1.00000000000000,\n",
" ((), (0, 2)): 1.0*exp(x_1),\n",
" ((), (2, 0)): 1.0*exp(x_1),\n",
" ((), (2, 2)): 1.0*exp(2*x_1)}\n"
]
}
],
"source": [
"Ric = gr.get_Ricci_tensor(cs)\n",
"pprint(Ric.values)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"or, in LaTeX:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$(1.0 e^{2 x_{1}})dx_2 \\otimes dx_2 + (1.0 e^{x_{1}})dx_2 \\otimes dx_0 + (1.0)dx_0 \\otimes dx_0 + (1.0 e^{x_{1}})dx_0 \\otimes dx_2$"
],
"text/plain": [
"(1.0*exp(2*x_1))x_2* \\otimes x_2* + (1.0*exp(x_1))x_2* \\otimes x_0* + (1.00000000000000)x_0* \\otimes x_0* + (1.0*exp(x_1))x_0* \\otimes x_2*"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Ric"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Scalar curvature"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{((), ()): 1.0/a**2}\n"
]
},
{
"data": {
"text/latex": [
"$(\\frac{1.0}{a^{2}})$"
],
"text/plain": [
"(1.0/a**2)"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"R = gr.get_scalar_curvature(cs, g)\n",
"pprint(R.values)\n",
"R"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Einstein tensor "
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{((), (0, 0)): 0.500000000000000,\n",
" ((), (0, 2)): 0.5*exp(x_1),\n",
" ((), (1, 1)): 0.500000000000000,\n",
" ((), (2, 0)): 0.5*exp(x_1),\n",
" ((), (2, 2)): 0.75*exp(2*x_1),\n",
" ((), (3, 3)): 0.500000000000000}\n"
]
}
],
"source": [
"G = gr.get_Einstein_tensor(cs, g)\n",
"pprint(G.values)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Hyperbolic metric in $\\mathbb{R}^2$ "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that these definitions are not restricted to tensors in a $4$ dimensional space. For example, let's consider another metric in $\\mathbb{R}^2$:\n",
"\n",
"$$ g = (1/y^2)(dx\\otimes dx + dy\\otimes dy) $$"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"x, y = sympy.symbols('x y')"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"values = {\n",
" (0,0): 1/y**2,\n",
" (1,1): 1/y**2\n",
"}\n",
"basis = [x, y]\n",
"g = gr.Tensor(basis, (0, 2), values)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$(\\frac{1}{y^{2}})dx \\otimes dx + (\\frac{1}{y^{2}})dy \\otimes dy$"
],
"text/plain": [
"(y**(-2))x* \\otimes x* + (y**(-2))y* \\otimes y*"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"g"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAE0AAAA5BAMAAACBlLtUAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUMhDNmavdInZEu2aC2vy2AAAACXBIWXMAAA7EAAAOxAGVKw4bAAACM0lEQVRIDbWVsWsUQRTGP+924t25l1uIvUuQEAjKWVplTaKWXlIkGoQspLMKFqJWR9BC0gTUJgi5JliaUpCAWIhpkqvEJkHzDxiUkIjFOju7szOzb7LZxinu3vu+37y3M7PsAOm4JYPi/9sviv3MvZ5FxcFZ3KXolyhQwFWiyMPQ1M1TOfbwIOAmm5r0cFFQgK3eQJutCdsp5n4AI2W4b8B4Jwa1etfERPPnBNhtm9zb9RWT4Rk75tymyRGICw2+Y3f8EhyvV4YjfVtROg7N9nwd47l1AE1smxSwB/zs5J9vAAtC02C+z49Equ0fz8nR1dssOVaDYw+0UiJkY+8DERjc3XxbNU1yn7p4zZ7OKCMXSc4/crx69CfnqjTlGvdXL/SVSiNZr+bXNqmrFMnVP54LlEqjjAt2qakpknNXvmoqDSU3j31qaorklt1QU1XopLLkdoaVp0XO49Ukk5zmGWH1v3NzVy8bHZOE9l3EvR4FCTfooRKW4JpdVI9KcK0u3N8Wzku0bP8WluD+JVzjyUnyumXcOx9O8v0lcCwobqkcZ+srPyaRVo+vo2pZBzBxpaf3bfYxaNkXoO/Gr0L2fHyfz4dcICNk8fSMw0tMBwSKBXF0ipv58MyKYbbHdcVZIHcU9Q57HjuFXKXVuYG5Df8sbmMbW1iPjPXGxclYhrxTCvviTXZJck7eq6Qa8Mo9FKq4V+U9beG+bIVCFfe0xU8l1mt+P91VTs3/rJKCyD3wlfsPO2CALSHlSmMAAAAASUVORK5CYII=\n",
"text/latex": [
"$$\\left[\\begin{matrix}\\frac{1}{y^{2}} & 0\\\\0 & \\frac{1}{y^{2}}\\end{matrix}\\right]$$"
],
"text/plain": [
"⎡1 ⎤\n",
"⎢── 0 ⎥\n",
"⎢ 2 ⎥\n",
"⎢y ⎥\n",
"⎢ ⎥\n",
"⎢ 1 ⎥\n",
"⎢0 ──⎥\n",
"⎢ 2⎥\n",
"⎣ y ⎦"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"gr.get_matrix_from_tensor(g)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$(-2.0)$"
],
"text/plain": [
"(-2.00000000000000)"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cs = gr.get_chrisoffel_symbols_from_metric(g)\n",
"gr.get_scalar_curvature(cs, g)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment