Notebook Status: Validated
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.
The module is organized as follows
The energy-momentum tensor for a massless scalar field is given by eq. (5.232) of B&S, which we right here in contravariant form
$$ T^{\mu\nu} = \partial^{\mu}\varphi\partial^{\nu}\varphi - \frac{1}{2}g^{\mu\nu}\left(\partial^{\lambda}\varphi\partial_{\lambda}\varphi\right)\ . $$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.
# Step 1.a: import all needed modules from NRPy+:
import sympy as sp # SymPy: The Python computer algebra package upon which NRPy+ depends
import NRPy_param_funcs as par # NRPy+: Parameter interface
import indexedexp as ixp # NRPy+: Symbolic indexed expression (e.g., tensors, vectors, etc.) support
import reference_metric as rfm # NRPy+: Reference metric support
import BSSN.BSSN_quantities as Bq # NRPy+: BSSN quantities
import BSSN.ADM_in_terms_of_BSSN as BtoA # NRPy+: ADM quantities in terms of BSSN quantities
import BSSN.ADMBSSN_tofrom_4metric as ADMg # NRPy+: ADM 4-metric to/from ADM or BSSN quantities
# Step 1.b: Set the coordinate system for the numerical grid
coord_system = "Spherical"
par.set_parval_from_str("reference_metric::CoordSystem",coord_system)
# Step 1.c: Set spatial dimension (must be 3 for BSSN, as BSSN is
# a 3+1-dimensional decomposition of the general
# relativistic field equations)
DIM = 3
par.set_parval_from_str("grid::DIM",DIM)
# Step 1.d: Given the chosen coordinate system, set up
# corresponding reference metric and needed
# reference metric quantities
# The following function call sets up the reference metric
# and related quantities, including rescaling matrices ReDD,
# ReU, and hatted quantities.
rfm.reference_metric()
# Step 1.e: Set the theta and phi axes to be the symmetry axes; i.e., axis "1" and "2",
# corresponding to the i1 and i2 directions. This sets all spatial derivatives
# in the theta and phi directions to zero (analytically).
par.set_parval_from_str("indexedexp::symmetry_axes","12")
# Step 1.e: Import all basic (unrescaled) BSSN scalars & tensors
Bq.BSSN_basic_tensors()
alpha = Bq.alpha
betaU = Bq.betaU
# Step 1.g: Define ADM quantities in terms of BSSN quantities
BtoA.ADM_in_terms_of_BSSN()
gammaDD = BtoA.gammaDD
gammaUU = BtoA.gammaUU
# Step 1.h: Define scalar field quantitites
sf_dD = ixp.declarerank1("sf_dD")
Pi = sp.Symbol("sfM",real=True)
Consider the ADM 4-metric (eq. 2.119 of B&S)
$$ g^{\mu\nu}=\begin{pmatrix} -\alpha^{-2} & \alpha^{-2}\beta^{i}\\ \alpha^{-2}\beta^{j} & \gamma^{ij} - \alpha^{-2}\beta^{i}\beta^{j} \end{pmatrix}\ , $$and the definition of the scalar field's conjugate momentum, $\Pi$, as given by eq. 2.522 of B&S
$$ \Pi\equiv-\frac{1}{\alpha}\left[\partial_{t}\varphi - \beta^{i}\partial_{i}\varphi\right]\ . $$Then we have
\begin{align} \partial^{t}\varphi &= g^{tt}\partial_{t}\varphi + g^{ti}\partial_{i}\varphi\nonumber\\ &= -\alpha^{-2}\partial_{t}\varphi + \alpha^{-2}\beta^{i}\partial_{i}\varphi\nonumber\\ &= \alpha^{-1}\left[-\frac{1}{\alpha}\left(\partial_{t}\varphi - \beta^{i}\partial_{i}\varphi\right)\right]\nonumber\\ &= \frac{\Pi}{\alpha}\ . \end{align}# Step 2a: Set up \partial^{t}\varphi = Pi/alpha
sf4dU = ixp.zerorank1(DIM=4)
sf4dU[0] = Pi / alpha
Next, we look at
\begin{align} \partial^{i}\varphi &= g^{it}\partial_{t}\varphi + g^{ij}\partial_{j}\varphi\nonumber\\ &=\alpha^{-2}\beta^{i}\partial_{t}\varphi + \gamma^{ij}\partial_{j}\varphi - \alpha^{-2}\beta^{i}\beta^{j}\partial_{j}\varphi\nonumber\\ &=-\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\\ &=-\frac{\Pi}{\alpha}\beta^{i} + \gamma^{ij}\partial_{j}\varphi\ . \end{align}# Step 2b: Set up \partial^{i}\varphi = -Pi*beta^{i}/alpha + gamma^{ij}\partial_{j}\varphi
for i in range(DIM):
sf4dU[i+1] = -Pi * betaU[i] / alpha
for j in range(DIM):
sf4dU[i+1] += gammaUU[i][j] * sf_dD[j]
The last step is to set up the contraction
\begin{align} \partial^{\lambda}\varphi\partial_{\lambda}\varphi &= \partial^{t}\varphi\partial_{t}\varphi + \partial^{i}\varphi\partial_{i}\varphi\nonumber\\ &=\frac{\Pi}{\alpha}\partial_{t}\varphi - \frac{\Pi}{\alpha}\beta^{i}\partial_{i}\varphi + \gamma^{ij}\partial_{i}\varphi\partial_{j}\varphi\nonumber\\ &= -\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\\ &= -\Pi^2 + \gamma^{ij}\partial_{i}\varphi\partial_{j}\varphi\ . \end{align}# Step 2c: Set up \partial^{i}\varphi\partial_{i}\varphi = -Pi**2 + gamma^{ij}\partial_{i}\varphi\partial_{j}\varphi
sf4d2 = -Pi**2
for i in range(DIM):
for j in range(DIM):
sf4d2 += gammaUU[i][j] * sf_dD[i] * sf_dD[j]
We start by setting up the ADM 4-metric $g^{\mu\nu}$, given by eq. (2.119) in B&S,
$$ g^{\mu\nu}=\begin{pmatrix} -\alpha^{-2} & \alpha^{-2}\beta^{i}\\ \alpha^{-2}\beta^{j} & \gamma^{ij} - \alpha^{-2}\beta^{i}\beta^{j} \end{pmatrix}\ . $$We do this be calling the BSSN.adm_four_metric_conversions.py module.
# Step 3a: Setting up g^{\mu\nu}
ADMg.g4UU_ito_BSSN_or_ADM("ADM",gammaDD=gammaDD,betaU=betaU,alpha=alpha, gammaUU=gammaUU)
g4UU = ADMg.g4UU
We then focus on the energy momentum tensor $T^{\mu\nu}$ for a massless scalar field, $\varphi$ (cf. eq. 5.232 of B&S with $V(\varphi)=0$)
$$ 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)\ . $$# Step 3b: Setting up T^{\mu\nu} for a massless scalar field
T4UU = ixp.zerorank2(DIM=4)
for mu in range(4):
for nu in range(4):
T4UU[mu][nu] = sf4dU[mu] * sf4dU[nu] - sp.Rational(1,2) * g4UU[mu][nu] * sf4d2
Here we perform a code validation. We verify agreement in the SymPy expressions for the energy-momentum tensor of a scalar field between
By default, we analyze the RHSs in Spherical coordinates, though other coordinate systems may be chosen.
import ScalarField.ScalarField_Tmunu as sfTmunu # NRPyCritCol: Scalar field energy-momentum tensor
sfTmunu.ScalarField_Tmunu()
print("Consistency check between this tutorial and the ScalarField.ScalarField_Tmunu.py module: ALL SHOULD BE ZERO\n")
for mu in range(4):
for nu in range(4):
print("T4UU["+str(mu)+"]["+str(nu)+"] - sfTmunu.T4UU["+str(mu)+"]["+str(nu)+"] = "+str(sp.simplify(T4UU[mu][nu] - sfTmunu.T4UU[mu][nu])))
Consistency check between this tutorial and the ScalarField.ScalarField_Tmunu.py module: ALL SHOULD BE ZERO T4UU[0][0] - sfTmunu.T4UU[0][0] = 0 T4UU[0][1] - sfTmunu.T4UU[0][1] = 0 T4UU[0][2] - sfTmunu.T4UU[0][2] = 0 T4UU[0][3] - sfTmunu.T4UU[0][3] = 0 T4UU[1][0] - sfTmunu.T4UU[1][0] = 0 T4UU[1][1] - sfTmunu.T4UU[1][1] = 0 T4UU[1][2] - sfTmunu.T4UU[1][2] = 0 T4UU[1][3] - sfTmunu.T4UU[1][3] = 0 T4UU[2][0] - sfTmunu.T4UU[2][0] = 0 T4UU[2][1] - sfTmunu.T4UU[2][1] = 0 T4UU[2][2] - sfTmunu.T4UU[2][2] = 0 T4UU[2][3] - sfTmunu.T4UU[2][3] = 0 T4UU[3][0] - sfTmunu.T4UU[3][0] = 0 T4UU[3][1] - sfTmunu.T4UU[3][1] = 0 T4UU[3][2] - sfTmunu.T4UU[3][2] = 0 T4UU[3][3] - sfTmunu.T4UU[3][3] = 0
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 Tutorial-ScalarField_Tmunu.pdf (Note that clicking on this link may not work; you may need to open the PDF file through another means.)
import cmdline_helper as cmd # NRPy+: Multi-platform Python command-line interface
cmd.output_Jupyter_notebook_to_LaTeXed_PDF("Tutorial-ScalarField_Tmunu")
Created Tutorial-ScalarField_Tmunu.tex, and compiled LaTeX file to PDF file Tutorial-ScalarField_Tmunu.pdf