{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\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:** Validated \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).\n",
"\n",
"## Python module containing the final expressions constructed here: **[ScalarField/ScalarField_Tmunu.py](../edit/ScalarField/ScalarField_Tmunu.py)**\n",
"\n",
"\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": [
"\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": [
"\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": [
"\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": [
"\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": [
"\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": [
"\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",
"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.9.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}