{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "<script async src=\"https://www.googletagmanager.com/gtag/js?id=UA-59152712-8\"></script>\n", "<script>\n", " window.dataLayer = window.dataLayer || [];\n", " function gtag(){dataLayer.push(arguments);}\n", " gtag('js', new Date());\n", "\n", " gtag('config', 'UA-59152712-8');\n", "</script>\n", "\n", "# Tutorial: Setting up the energy-momentum tensor of a massless scalar field\n", "\n", "## Authors: Leonardo Werneck & Zach Etienne\n", "\n", "# This module documents the construction of the energy-momentum tensor of a massless scalar field.\n", "\n", "**Notebook Status:** <font color='green'><b> Validated </b></font>\n", "\n", "**Validation Notes:** The expressions generated by the NRPy+ module corresponding to this tutorial notebook are used to demonstrate that the initial data for a massless scalar field satisfy Einstein's equations as expected [in this tutorial notebook](Tutorial-Start_to_Finish-BSSNCurvilinear-Setting_up_ScalarField_initial_data).</font>\n", "\n", "## Python module containing the final expressions constructed here: **[ScalarField/ScalarField_Tmunu.py](../edit/ScalarField/ScalarField_Tmunu.py)**\n", "\n", "<a id='toc'></a>\n", "\n", "# Table of Contents\n", "$$\\label{toc}$$\n", "\n", "The module is organized as follows\n", "\n", "0. [Preliminaries](#preliminaries): The energy momentum tensor of a massless scalar field\n", "1. [Step 1](#initializenrpy): Initialize core NRPy+ modules\n", "1. [Step 2](#sf4d): The 4-derivatives of the scalar field: $\\partial^{\\mu}\\varphi$\n", "1. [Step 3](#energy_momentum_tensor): The energy momentum tensor: $T^{\\mu\\nu}$\n", "1. [Step 4](#code_validation): Validation against the [ScalarField/ScalarField_Tmunu.py](../edit/ScalarField/ScalarField_Tmunu.py) module\n", "1. [Step 5](#latex_pdf_output): Output this module to $\\LaTeX$-formatted PDF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='preliminaries'></a>\n", "\n", "# Preliminaries: The energy momentum tensor of a massless scalar field \\[Back to [top](#toc)\\]\n", "$$\\label{preliminaries}$$\n", "\n", "The energy-momentum tensor for a massless scalar field is given by eq. (5.232) of [B&S](https://books.google.com.br/books/about/Numerical_Relativity.html?id=dxU1OEinvRUC&redir_esc=y), which we right here in contravariant form\n", "\n", "$$\n", "T^{\\mu\\nu} = \\partial^{\\mu}\\varphi\\partial^{\\nu}\\varphi - \\frac{1}{2}g^{\\mu\\nu}\\left(\\partial^{\\lambda}\\varphi\\partial_{\\lambda}\\varphi\\right)\\ .\n", "$$\n", "\n", "This is a key tensor in the problem of gravitational collapse of a massless scalar field, since it will be responsible for how the geometry changes in the presence of the scalar field. In this tutorial module we will be implementing this tensor." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='initializenrpy'></a>\n", "\n", "# Step 1: Initialize core NRPy+ modules \\[Back to [top](#toc)\\]\n", "$$\\label{initializenrpy}$$\n", "\n", "Let's start by importing all the needed modules from NRPy+:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2021-06-15T10:05:20.101241Z", "iopub.status.busy": "2021-06-15T10:05:20.100775Z", "iopub.status.idle": "2021-06-15T10:05:20.682804Z", "shell.execute_reply": "2021-06-15T10:05:20.682226Z" } }, "outputs": [], "source": [ "# Step 1.a: import all needed modules from NRPy+:\n", "import sympy as sp # SymPy: The Python computer algebra package upon which NRPy+ depends\n", "import NRPy_param_funcs as par # NRPy+: Parameter interface\n", "import indexedexp as ixp # NRPy+: Symbolic indexed expression (e.g., tensors, vectors, etc.) support\n", "import reference_metric as rfm # NRPy+: Reference metric support\n", "import BSSN.BSSN_quantities as Bq # NRPy+: BSSN quantities\n", "import BSSN.ADM_in_terms_of_BSSN as BtoA # NRPy+: ADM quantities in terms of BSSN quantities\n", "import BSSN.ADMBSSN_tofrom_4metric as ADMg # NRPy+: ADM 4-metric to/from ADM or BSSN quantities\n", "\n", "# Step 1.b: Set the coordinate system for the numerical grid\n", "coord_system = \"Spherical\"\n", "par.set_parval_from_str(\"reference_metric::CoordSystem\",coord_system)\n", "\n", "# Step 1.c: Set spatial dimension (must be 3 for BSSN, as BSSN is\n", "# a 3+1-dimensional decomposition of the general\n", "# relativistic field equations)\n", "DIM = 3\n", "par.set_parval_from_str(\"grid::DIM\",DIM)\n", "\n", "# Step 1.d: Given the chosen coordinate system, set up\n", "# corresponding reference metric and needed\n", "# reference metric quantities\n", "# The following function call sets up the reference metric\n", "# and related quantities, including rescaling matrices ReDD,\n", "# ReU, and hatted quantities.\n", "rfm.reference_metric()\n", "\n", "# Step 1.e: Set the theta and phi axes to be the symmetry axes; i.e., axis \"1\" and \"2\",\n", "# corresponding to the i1 and i2 directions. This sets all spatial derivatives\n", "# in the theta and phi directions to zero (analytically).\n", "par.set_parval_from_str(\"indexedexp::symmetry_axes\",\"12\")\n", "\n", "# Step 1.e: Import all basic (unrescaled) BSSN scalars & tensors\n", "Bq.BSSN_basic_tensors()\n", "alpha = Bq.alpha\n", "betaU = Bq.betaU\n", "\n", "# Step 1.g: Define ADM quantities in terms of BSSN quantities\n", "BtoA.ADM_in_terms_of_BSSN()\n", "gammaDD = BtoA.gammaDD\n", "gammaUU = BtoA.gammaUU\n", "\n", "# Step 1.h: Define scalar field quantitites\n", "sf_dD = ixp.declarerank1(\"sf_dD\")\n", "Pi = sp.Symbol(\"sfM\",real=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='sf4d'></a>\n", "\n", "# Step 2: The 4-derivatives of the scalar field: $\\partial^{\\mu}\\varphi$ \\[Back to [top](#toc)\\]\n", "$$\\label{sf4d}$$\n", "\n", "Consider the ADM 4-metric (eq. 2.119 of B&S)\n", "\n", "$$\n", "g^{\\mu\\nu}=\\begin{pmatrix}\n", "-\\alpha^{-2} & \\alpha^{-2}\\beta^{i}\\\\\n", "\\alpha^{-2}\\beta^{j} & \\gamma^{ij} - \\alpha^{-2}\\beta^{i}\\beta^{j}\n", "\\end{pmatrix}\\ ,\n", "$$\n", "\n", "and the definition of the scalar field's conjugate momentum, $\\Pi$, as given by eq. 2.522 of B&S\n", "\n", "$$\n", "\\Pi\\equiv-\\frac{1}{\\alpha}\\left[\\partial_{t}\\varphi - \\beta^{i}\\partial_{i}\\varphi\\right]\\ .\n", "$$\n", "\n", "Then we have\n", "\n", "\\begin{align}\n", "\\partial^{t}\\varphi &= g^{tt}\\partial_{t}\\varphi + g^{ti}\\partial_{i}\\varphi\\nonumber\\\\\n", "&= -\\alpha^{-2}\\partial_{t}\\varphi + \\alpha^{-2}\\beta^{i}\\partial_{i}\\varphi\\nonumber\\\\\n", "&= \\alpha^{-1}\\left[-\\frac{1}{\\alpha}\\left(\\partial_{t}\\varphi - \\beta^{i}\\partial_{i}\\varphi\\right)\\right]\\nonumber\\\\\n", "&= \\frac{\\Pi}{\\alpha}\\ .\n", "\\end{align}" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2021-06-15T10:05:20.686039Z", "iopub.status.busy": "2021-06-15T10:05:20.685529Z", "iopub.status.idle": "2021-06-15T10:05:20.687579Z", "shell.execute_reply": "2021-06-15T10:05:20.687068Z" } }, "outputs": [], "source": [ "# Step 2a: Set up \\partial^{t}\\varphi = Pi/alpha\n", "sf4dU = ixp.zerorank1(DIM=4)\n", "sf4dU[0] = Pi / alpha" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we look at\n", "\n", "\\begin{align}\n", "\\partial^{i}\\varphi &= g^{it}\\partial_{t}\\varphi + g^{ij}\\partial_{j}\\varphi\\nonumber\\\\\n", "&=\\alpha^{-2}\\beta^{i}\\partial_{t}\\varphi + \\gamma^{ij}\\partial_{j}\\varphi - \\alpha^{-2}\\beta^{i}\\beta^{j}\\partial_{j}\\varphi\\nonumber\\\\\n", "&=-\\alpha^{-1}\\beta^{i}\\left[-\\frac{1}{\\alpha}\\left(\\partial_{t}\\varphi-\\beta^{j}\\partial_{j}\\varphi\\right)\\right] + \\gamma^{ij}\\partial_{j}\\varphi\\nonumber\\\\\n", "&=-\\frac{\\Pi}{\\alpha}\\beta^{i} + \\gamma^{ij}\\partial_{j}\\varphi\\ .\n", "\\end{align}" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2021-06-15T10:05:20.695054Z", "iopub.status.busy": "2021-06-15T10:05:20.694609Z", "iopub.status.idle": "2021-06-15T10:05:20.696519Z", "shell.execute_reply": "2021-06-15T10:05:20.696108Z" } }, "outputs": [], "source": [ "# Step 2b: Set up \\partial^{i}\\varphi = -Pi*beta^{i}/alpha + gamma^{ij}\\partial_{j}\\varphi\n", "for i in range(DIM):\n", " sf4dU[i+1] = -Pi * betaU[i] / alpha\n", " for j in range(DIM):\n", " sf4dU[i+1] += gammaUU[i][j] * sf_dD[j]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The last step is to set up the contraction\n", "\n", "\\begin{align}\n", "\\partial^{\\lambda}\\varphi\\partial_{\\lambda}\\varphi &= \\partial^{t}\\varphi\\partial_{t}\\varphi + \\partial^{i}\\varphi\\partial_{i}\\varphi\\nonumber\\\\\n", "&=\\frac{\\Pi}{\\alpha}\\partial_{t}\\varphi - \\frac{\\Pi}{\\alpha}\\beta^{i}\\partial_{i}\\varphi + \\gamma^{ij}\\partial_{i}\\varphi\\partial_{j}\\varphi\\nonumber\\\\\n", "&= -\\Pi\\left[-\\frac{1}{\\alpha}\\left(\\partial_{t}\\varphi-\\beta^{i}\\partial_{i}\\varphi\\right)\\right] + \\gamma^{ij}\\partial_{i}\\varphi\\partial_{j}\\varphi\\nonumber\\\\\n", "&= -\\Pi^2 + \\gamma^{ij}\\partial_{i}\\varphi\\partial_{j}\\varphi\\ .\n", "\\end{align}" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2021-06-15T10:05:20.700423Z", "iopub.status.busy": "2021-06-15T10:05:20.700006Z", "iopub.status.idle": "2021-06-15T10:05:20.702056Z", "shell.execute_reply": "2021-06-15T10:05:20.701648Z" } }, "outputs": [], "source": [ "# Step 2c: Set up \\partial^{i}\\varphi\\partial_{i}\\varphi = -Pi**2 + gamma^{ij}\\partial_{i}\\varphi\\partial_{j}\\varphi\n", "sf4d2 = -Pi**2\n", "for i in range(DIM):\n", " for j in range(DIM):\n", " sf4d2 += gammaUU[i][j] * sf_dD[i] * sf_dD[j]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='energy_momentum_tensor'></a>\n", "\n", "# Step 3: The energy momentum tensor: $T^{\\mu\\nu}$ \\[Back to [top](#toc)\\]\n", "$$\\label{energy_momentum_tensor}$$\n", "\n", "We start by setting up the ADM 4-metric $g^{\\mu\\nu}$, given by eq. (2.119) in [B&S](https://books.google.com.br/books/about/Numerical_Relativity.html?id=dxU1OEinvRUC&redir_esc=y),\n", "\n", "$$\n", "g^{\\mu\\nu}=\\begin{pmatrix}\n", "-\\alpha^{-2} & \\alpha^{-2}\\beta^{i}\\\\\n", "\\alpha^{-2}\\beta^{j} & \\gamma^{ij} - \\alpha^{-2}\\beta^{i}\\beta^{j}\n", "\\end{pmatrix}\\ .\n", "$$\n", "\n", "We do this be calling the [BSSN.adm_four_metric_conversions.py](../edit/BSSN/adm_four_metric_conversions.py) module." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2021-06-15T10:05:20.711589Z", "iopub.status.busy": "2021-06-15T10:05:20.711182Z", "iopub.status.idle": "2021-06-15T10:05:20.713256Z", "shell.execute_reply": "2021-06-15T10:05:20.712745Z" } }, "outputs": [], "source": [ "# Step 3a: Setting up g^{\\mu\\nu}\n", "ADMg.g4UU_ito_BSSN_or_ADM(\"ADM\",gammaDD=gammaDD,betaU=betaU,alpha=alpha, gammaUU=gammaUU)\n", "g4UU = ADMg.g4UU" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We then focus on the energy momentum tensor $T^{\\mu\\nu}$ for a massless scalar field, $\\varphi$ (cf. eq. 5.232 of [B&S](https://books.google.com.br/books/about/Numerical_Relativity.html?id=dxU1OEinvRUC&redir_esc=y) with $V(\\varphi)=0$)\n", "\n", "$$\n", "T^{\\mu\\nu} = \\partial^{\\mu}\\varphi\\partial^{\\nu}\\varphi - \\frac{1}{2}g^{\\mu\\nu}\\left(\\underbrace{\\partial_{\\lambda}\\varphi\\partial^{\\lambda}\\varphi}_{\\equiv \\rm sf4d2}\\right)\\ .\n", "$$" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2021-06-15T10:05:20.726077Z", "iopub.status.busy": "2021-06-15T10:05:20.724741Z", "iopub.status.idle": "2021-06-15T10:05:20.727857Z", "shell.execute_reply": "2021-06-15T10:05:20.727448Z" } }, "outputs": [], "source": [ "# Step 3b: Setting up T^{\\mu\\nu} for a massless scalar field\n", "T4UU = ixp.zerorank2(DIM=4)\n", "for mu in range(4):\n", " for nu in range(4):\n", " T4UU[mu][nu] = sf4dU[mu] * sf4dU[nu] - sp.Rational(1,2) * g4UU[mu][nu] * sf4d2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='code_validation'></a>\n", "\n", "# Step 4: Validation against the [ScalarField/ScalarField_Tmunu.py](../edit/ScalarField/ScalarField_Tmunu.py) module \\[Back to [top](#toc)\\]\n", "$$\\label{code_validation}$$\n", "\n", "Here we perform a code validation. We verify agreement in the SymPy expressions for the energy-momentum tensor of a scalar field between\n", "1. this tutorial notebook and \n", "2. the [ScalarField/ScalarField_Tmunu.py](../edit/ScalarField/ScalarField/ScalarField_Tmunu.py) NRPy+ module.\n", "\n", "By default, we analyze the RHSs in Spherical coordinates, though other coordinate systems may be chosen." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2021-06-15T10:05:20.730832Z", "iopub.status.busy": "2021-06-15T10:05:20.730324Z", "iopub.status.idle": "2021-06-15T10:05:22.412864Z", "shell.execute_reply": "2021-06-15T10:05:22.412372Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Consistency check between this tutorial and the ScalarField.ScalarField_Tmunu.py module: ALL SHOULD BE ZERO\n", "\n", "T4UU[0][0] - sfTmunu.T4UU[0][0] = 0\n", "T4UU[0][1] - sfTmunu.T4UU[0][1] = 0\n", "T4UU[0][2] - sfTmunu.T4UU[0][2] = 0\n", "T4UU[0][3] - sfTmunu.T4UU[0][3] = 0\n", "T4UU[1][0] - sfTmunu.T4UU[1][0] = 0\n", "T4UU[1][1] - sfTmunu.T4UU[1][1] = 0\n", "T4UU[1][2] - sfTmunu.T4UU[1][2] = 0\n", "T4UU[1][3] - sfTmunu.T4UU[1][3] = 0\n", "T4UU[2][0] - sfTmunu.T4UU[2][0] = 0\n", "T4UU[2][1] - sfTmunu.T4UU[2][1] = 0\n", "T4UU[2][2] - sfTmunu.T4UU[2][2] = 0\n", "T4UU[2][3] - sfTmunu.T4UU[2][3] = 0\n", "T4UU[3][0] - sfTmunu.T4UU[3][0] = 0\n", "T4UU[3][1] - sfTmunu.T4UU[3][1] = 0\n", "T4UU[3][2] - sfTmunu.T4UU[3][2] = 0\n", "T4UU[3][3] - sfTmunu.T4UU[3][3] = 0\n" ] } ], "source": [ "import ScalarField.ScalarField_Tmunu as sfTmunu # NRPyCritCol: Scalar field energy-momentum tensor\n", "sfTmunu.ScalarField_Tmunu()\n", "\n", "print(\"Consistency check between this tutorial and the ScalarField.ScalarField_Tmunu.py module: ALL SHOULD BE ZERO\\n\")\n", "\n", "for mu in range(4):\n", " for nu in range(4):\n", " print(\"T4UU[\"+str(mu)+\"][\"+str(nu)+\"] - sfTmunu.T4UU[\"+str(mu)+\"][\"+str(nu)+\"] = \"+str(sp.simplify(T4UU[mu][nu] - sfTmunu.T4UU[mu][nu])))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='latex_pdf_output'></a>\n", "\n", "# Step 5: Output this module to $\\LaTeX$-formatted PDF file \\[Back to [top](#toc)\\]\n", "$$\\label{latex_pdf_output}$$\n", "\n", "The following code cell converts this Jupyter notebook into a proper, clickable $\\LaTeX$-formatted PDF file. After the cell is successfully run, the generated PDF may be found in the root NRPy+ tutorial directory, with filename\n", "[Tutorial-ScalarField_Tmunu.pdf](Tutorial-ScalarField_Tmunu.pdf) (Note that clicking on this link may not work; you may need to open the PDF file through another means.)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2021-06-15T10:05:22.415760Z", "iopub.status.busy": "2021-06-15T10:05:22.415220Z", "iopub.status.idle": "2021-06-15T10:05:24.657551Z", "shell.execute_reply": "2021-06-15T10:05:24.657002Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created Tutorial-ScalarField_Tmunu.tex, and compiled LaTeX file to PDF file\n", " Tutorial-ScalarField_Tmunu.pdf\n" ] } ], "source": [ "import cmdline_helper as cmd # NRPy+: Multi-platform Python command-line interface\n", "cmd.output_Jupyter_notebook_to_LaTeXed_PDF(\"Tutorial-ScalarField_Tmunu\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.10.11" } }, "nbformat": 4, "nbformat_minor": 4 }