{
 "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",
    "# Converting between the 4-metric $g_{\\mu\\nu}$ and ADM variables $\\left\\{\\gamma_{ij}, \\alpha, \\beta^i\\right\\}$ or BSSN variables $\\left\\{h_{ij}, {\\rm cf}, \\alpha, {\\rm vet}^i\\right\\}$\n",
    "## Author: Zach Etienne\n",
    "\n",
    "## This notebook presents the NRPy+ Python module [BSSN/ADMBSSN_tofrom_4metric.py](../edit/BSSN/ADMBSSN_tofrom_4metric.py), which facilitates conversion between the 4-metric and ADM or BSSN variables. The notebook also outlines the steps to write ADM/BSSN metric quantities in terms of 4-metric $g_{\\mu\\nu}$, while excluding extrinsic curvature $K_{ij}$, or the BSSN $\\bar{A}_{ij}$, $K$.\n",
    "\n",
    "**Notebook Status:** <font color='orange'><b> Self-validated, some additional tests performed </b></font>\n",
    "\n",
    "**Validation Notes:** This tutorial notebook has been confirmed to be self-consistent with its corresponding NRPy+ module, as documented [below](#code_validation). In addition, the construction of $g_{\\mu\\nu}$ and $g^{\\mu\\nu}$ from BSSN variables has passed the test $g^{\\mu\\nu}g_{\\mu\\nu}=4$ [below](#validationcontraction). **Additional validation tests may have been performed, but are as yet, undocumented. (TODO)**\n",
    "\n",
    "### NRPy+ Source Code for this module: [BSSN/ADMBSSN_tofrom_4metric.py](../edit/BSSN/ADMBSSN_tofrom_4metric.py)\n",
    "\n",
    "[comment]: <> (Introduction: TODO)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='toc'></a>\n",
    "\n",
    "# Table of Contents\n",
    "$$\\label{toc}$$ \n",
    "\n",
    "This notebook is organized as follows\n",
    "\n",
    "1. [Step 1](#setup_ADM_quantities): `setup_ADM_quantities(inputvars)`: If `inputvars=\"ADM\"` declare ADM quantities $\\left\\{\\gamma_{ij},\\beta^i,\\alpha\\right\\}$; if `inputvars=\"ADM\"` define ADM quantities in terms of BSSN quantities\n",
    "1. [Step 2](#admbssn_to_fourmetric): Write 4-metric $g_{\\mu\\nu}$ and its inverse $g^{\\mu\\nu}$ in terms of ADM or BSSN quantities\n",
    "    1. [Step 2.a](#admbssn_to_fourmetric_lower): 4-metric $g_{\\mu\\nu}$ in terms of ADM or BSSN quantities\n",
    "    1. [Step 2.b](#admbssn_to_fourmetric_inv): 4-metric inverse $g^{\\mu\\nu}$ in terms of ADM or BSSN quantities\n",
    "    1. [Step 2.c](#validationcontraction): Validation check: Confirm $g_{\\mu\\nu}g^{\\mu\\nu}=4$\n",
    "1. [Step 3](#fourmetric_to_admbssn): Write ADM/BSSN metric quantities in terms of 4-metric $g_{\\mu\\nu}$ (Excludes extrinsic curvature $K_{ij}$ or the BSSN $\\bar{A}_{ij}$, $K$)\n",
    "    1. [Step 3.a](#adm_ito_fourmetric_validate): ADM in terms of 4-metric validation: Confirm $\\gamma_{ij}\\gamma^{ij}=3$\n",
    "    1. [Step 3.b](#bssn_ito_fourmetric_validate): BSSN in terms of 4-metric validation: Confirm $\\bar{\\gamma}_{ij}\\bar{\\gamma}^{ij}=3$\n",
    "1. [Step 4](#code_validation): Code Validation against `BSSN.ADMBSSN_tofrom_4metric` NRPy+ module\n",
    "1. [Step 5](#latex_pdf_output): Output this notebook to $\\LaTeX$-formatted PDF file"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='setup_ADM_quantities'></a>\n",
    "\n",
    "# Step 1: `setup_ADM_quantities(inputvars)`: If `inputvars=\"ADM\"` declare ADM quantities $\\left\\{\\gamma_{ij},\\beta^i,\\alpha\\right\\}$; if `inputvars=\"ADM\"` define ADM quantities in terms of BSSN quantities \\[Back to [top](#toc)\\]\n",
    "$$\\label{setup_ADM_quantities}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:04:53.262855Z",
     "iopub.status.busy": "2021-03-07T17:04:53.261631Z",
     "iopub.status.idle": "2021-03-07T17:04:53.587660Z",
     "shell.execute_reply": "2021-03-07T17:04:53.586941Z"
    }
   },
   "outputs": [],
   "source": [
    "import sympy as sp\n",
    "import NRPy_param_funcs as par\n",
    "import indexedexp as ixp\n",
    "import sys\n",
    "\n",
    "def setup_ADM_quantities(inputvars):\n",
    "    if inputvars == \"ADM\":\n",
    "        gammaDD = ixp.declarerank2(\"gammaDD\", \"sym01\")\n",
    "        betaU = ixp.declarerank1(\"betaU\")\n",
    "        alpha = sp.symbols(\"alpha\", real=True)\n",
    "    elif inputvars == \"BSSN\":\n",
    "        import BSSN.ADM_in_terms_of_BSSN as AitoB\n",
    "\n",
    "        # Construct gamma_{ij} in terms of cf & gammabar_{ij}\n",
    "        AitoB.ADM_in_terms_of_BSSN()\n",
    "        gammaDD = AitoB.gammaDD\n",
    "        # Next construct beta^i in terms of vet^i and reference metric quantities\n",
    "        import BSSN.BSSN_quantities as Bq\n",
    "\n",
    "        Bq.BSSN_basic_tensors()\n",
    "        betaU = Bq.betaU\n",
    "        alpha = sp.symbols(\"alpha\", real=True)\n",
    "    else:\n",
    "        print(\"inputvars = \" + str(inputvars) + \" not supported. Please choose ADM or BSSN.\")\n",
    "        sys.exit(1)\n",
    "    return gammaDD,betaU,alpha"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='admbssn_to_fourmetric'></a>\n",
    "\n",
    "# Step 2: Write 4-metric $g_{\\mu\\nu}$ and its inverse $g^{\\mu\\nu}$ in terms of ADM or BSSN variables \\[Back to [top](#toc)\\]\n",
    "$$\\label{admbssn_to_fourmetric}$$\n",
    "\n",
    "<a id='admbssn_to_fourmetric_lower'></a>\n",
    "\n",
    "## Step 2.a: 4-metric $g_{\\mu\\nu}$ in terms of ADM or BSSN variables \\[Back to [top](#toc)\\]\n",
    "$$\\label{admbssn_to_fourmetric_lower}$$\n",
    "\n",
    "Given ADM variables $\\left\\{\\gamma_{ij},\\beta^i,\\alpha \\right\\}$, which themselves may be written in terms of the rescaled BSSN curvilinear variables $\\left\\{h_{ij},{\\rm cf},\\mathcal{V}^i,\\alpha \\right\\}$ for our chosen reference metric via simple function calls to `ADM_in_terms_of_BSSN()` and `BSSN_quantities.BSSN_basic_tensors()`, we are to construct the 4-metric $g_{\\mu\\nu}$. \n",
    "\n",
    "We accomplish this via Eq. 2.122 (which can be trivially derived from the ADM 3+1 line element) of Baumgarte & Shapiro's *Numerical Relativity* (henceforth B&S):\n",
    "$$\n",
    "g_{\\mu\\nu} = \\begin{pmatrix} \n",
    "-\\alpha^2 + \\beta^k \\beta_k & \\beta_i \\\\\n",
    "\\beta_j & \\gamma_{ij}\n",
    "\\end{pmatrix},\n",
    "$$\n",
    "where the shift vector $\\beta^i$ is lowered via (Eq. 2.121):\n",
    "\n",
    "$$\\beta_k = \\gamma_{ik} \\beta^i.$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:04:53.597249Z",
     "iopub.status.busy": "2021-03-07T17:04:53.596001Z",
     "iopub.status.idle": "2021-03-07T17:04:53.598438Z",
     "shell.execute_reply": "2021-03-07T17:04:53.598945Z"
    }
   },
   "outputs": [],
   "source": [
    "def g4DD_ito_BSSN_or_ADM(inputvars):\n",
    "    # Step 0: Declare g4DD as globals, to make interfacing with other modules/functions easier\n",
    "    global g4DD\n",
    "\n",
    "    # Step 1: Check that inputvars is set to a supported value\n",
    "    gammaDD,betaU,alpha = setup_ADM_quantities(inputvars)\n",
    "\n",
    "    # Step 2: Compute g4DD = g_{mu nu}:\n",
    "    # To get \\gamma_{\\mu \\nu} = gamma4DD[mu][nu], we'll need to construct the 4-metric, using Eq. 2.122 in B&S:\n",
    "    g4DD = ixp.zerorank2(DIM=4)\n",
    "\n",
    "    # Step 2.a: Compute beta_i via Eq. 2.121 in B&S\n",
    "    betaD = ixp.zerorank1()\n",
    "    for i in range(3):\n",
    "        for j in range(3):\n",
    "            betaD[i] += gammaDD[i][j] * betaU[j]\n",
    "\n",
    "    # Step 2.b: Compute beta_i beta^i, the beta contraction.\n",
    "    beta2 = sp.sympify(0)\n",
    "    for i in range(3):\n",
    "        beta2 += betaU[i] * betaD[i]\n",
    "\n",
    "    # Step 2.c: Construct g4DD via Eq. 2.122 in B&S\n",
    "    g4DD[0][0] = -alpha ** 2 + beta2\n",
    "    for mu in range(1, 4):\n",
    "        g4DD[mu][0] = g4DD[0][mu] = betaD[mu - 1]\n",
    "    for mu in range(1, 4):\n",
    "        for nu in range(1, 4):\n",
    "            g4DD[mu][nu] = gammaDD[mu - 1][nu - 1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='admbssn_to_fourmetric_inv'></a>\n",
    "\n",
    "## Step 2.b: Inverse 4-metric $g^{\\mu\\nu}$ in terms of ADM or BSSN variables \\[Back to [top](#toc)\\]\n",
    "$$\\label{admbssn_to_fourmetric_inv}$$ \n",
    "\n",
    "B&S also provide a convenient form for the inverse 4-metric (Eq. 2.119; also Eq. 4.49 in [Gourgoulhon](https://arxiv.org/pdf/gr-qc/0703035.pdf)):\n",
    "$$\n",
    "g^{\\mu\\nu} = \\gamma^{\\mu\\nu} - n^\\mu n^\\nu = \n",
    "\\begin{pmatrix} \n",
    "-\\frac{1}{\\alpha^2} & \\frac{\\beta^i}{\\alpha^2} \\\\\n",
    "\\frac{\\beta^i}{\\alpha^2} & \\gamma^{ij} - \\frac{\\beta^i\\beta^j}{\\alpha^2}\n",
    "\\end{pmatrix},\n",
    "$$\n",
    "where the unit normal vector to the hypersurface is given by $n^{\\mu} = \\left(\\alpha^{-1},-\\beta^i/\\alpha\\right)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:04:53.606601Z",
     "iopub.status.busy": "2021-03-07T17:04:53.605941Z",
     "iopub.status.idle": "2021-03-07T17:04:53.608043Z",
     "shell.execute_reply": "2021-03-07T17:04:53.608578Z"
    }
   },
   "outputs": [],
   "source": [
    "def g4UU_ito_BSSN_or_ADM(inputvars):\n",
    "    # Step 0: Declare g4UU as globals, to make interfacing with other modules/functions easier\n",
    "    global g4UU\n",
    "\n",
    "    # Step 1: Check that inputvars is set to a supported value\n",
    "    gammaDD,betaU,alpha = setup_ADM_quantities(inputvars)\n",
    "\n",
    "    # Step 2: Compute g4UU = g_{mu nu}:\n",
    "    # To get \\gamma^{\\mu \\nu} = gamma4UU[mu][nu], we'll need to use Eq. 2.119 in B&S.\n",
    "    g4UU = ixp.zerorank2(DIM=4)\n",
    "\n",
    "    # Step 3: Construct g4UU = g^{mu nu}\n",
    "    # Step 3.a: Compute gammaUU based on provided gammaDD:\n",
    "    gammaUU, _gammaDET = ixp.symm_matrix_inverter3x3(gammaDD)\n",
    "\n",
    "    # Then evaluate g4UU:\n",
    "    g4UU = ixp.zerorank2(DIM=4)\n",
    "\n",
    "    g4UU[0][0] = -1 / alpha**2\n",
    "    for mu in range(1,4):\n",
    "        g4UU[0][mu] = g4UU[mu][0] = betaU[mu-1]/alpha**2\n",
    "    for mu in range(1,4):\n",
    "        for nu in range(1,4):\n",
    "            g4UU[mu][nu] = gammaUU[mu-1][nu-1] - betaU[mu-1]*betaU[nu-1]/alpha**2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='validationcontraction'></a>\n",
    "\n",
    "## Step 2.c: Validation check: Confirm $g_{\\mu\\nu}g^{\\mu\\nu}=4$ \\[Back to [top](#toc)\\]\n",
    "$$\\label{validationcontraction}$$ \n",
    "\n",
    "Next we compute $g^{\\mu\\nu} g_{\\mu\\nu}$ as a validation check. It should equal 4:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:04:53.614947Z",
     "iopub.status.busy": "2021-03-07T17:04:53.613945Z",
     "iopub.status.idle": "2021-03-07T17:04:55.800662Z",
     "shell.execute_reply": "2021-03-07T17:04:55.801196Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TEST PASSED!\n"
     ]
    }
   ],
   "source": [
    "g4DD_ito_BSSN_or_ADM(\"BSSN\")\n",
    "g4UU_ito_BSSN_or_ADM(\"BSSN\")\n",
    "contraction = 0\n",
    "for mu in range(4):\n",
    "    for nu in range(4):\n",
    "        contraction += g4DD[mu][nu]*g4UU[mu][nu]\n",
    "if sp.simplify(contraction) == sp.sympify(4):\n",
    "    print(\"TEST PASSED!\")\n",
    "else:\n",
    "    print(\"TEST FAILED: \"+str(contraction)+\" does not apparently equal 4.\")\n",
    "    sys.exit(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='fourmetric_to_admbssn'></a>\n",
    "\n",
    "# Step 3: Write ADM/BSSN metric quantities in terms of 4-metric $g_{\\mu\\nu}$ (Excludes extrinsic curvature $K_{ij}$, the BSSN $a_{ij}$, $K$, and $\\lambda^i$) \\[Back to [top](#toc)\\]\n",
    "$$\\label{fourmetric_to_admbssn}$$ \n",
    "\n",
    "Given $g_{\\mu\\nu}$, we now compute ADM/BSSN metric quantities, excluding extrinsic curvature. \n",
    "\n",
    "Let's start by computing the ADM quantities in terms of the 4-metric $g_{\\mu\\nu}$.\n",
    "\n",
    "Recall that\n",
    "$$\n",
    "g_{\\mu\\nu} = \\begin{pmatrix} \n",
    "-\\alpha^2 + \\beta^k \\beta_k & \\beta_i \\\\\n",
    "\\beta_j & \\gamma_{ij}\n",
    "\\end{pmatrix}.\n",
    "$$\n",
    "\n",
    "From this equation, we immediately obtain $\\gamma_{ij}$. However we need $\\beta^i$ and $\\alpha$. After computing the inverse of $\\gamma_{ij}$, $\\gamma^{ij}$, we raise $\\beta_j$ via $\\beta^i=\\gamma^{ij} \\beta_j$ and then compute $\\alpha$ via $\\alpha = \\sqrt{\\beta^k \\beta_k - g_{00}}$. To convert to BSSN variables $\\left\\{h_{ij},{\\rm cf},\\mathcal{V}^i,\\alpha \\right\\}$, we need only convert from ADM via function calls to [`BSSN.BSSN_in_terms_of_ADM`](../edit/BSSN/BSSN_in_terms_of_ADM.py) ([**tutorial**](Tutorial-BSSN_in_terms_of_ADM.ipynb))."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:04:55.812488Z",
     "iopub.status.busy": "2021-03-07T17:04:55.811792Z",
     "iopub.status.idle": "2021-03-07T17:04:55.814035Z",
     "shell.execute_reply": "2021-03-07T17:04:55.814668Z"
    }
   },
   "outputs": [],
   "source": [
    "def BSSN_or_ADM_ito_g4DD(inputvars):\n",
    "    # Step 0: Declare output variables as globals, to make interfacing with other modules/functions easier\n",
    "    if inputvars == \"ADM\":\n",
    "        global gammaDD,betaU,alpha\n",
    "    elif inputvars == \"BSSN\":\n",
    "        global hDD,cf,vetU,alpha\n",
    "    else:\n",
    "        print(\"inputvars = \" + str(inputvars) + \" not supported. Please choose ADM or BSSN.\")\n",
    "        sys.exit(1)\n",
    "\n",
    "    # Step 1: declare g4DD as symmetric rank-4 tensor:\n",
    "    g4DD    = ixp.declarerank2(\"g4DD\",\"sym01\",DIM=4)\n",
    "\n",
    "    # Step 2: Compute gammaDD & betaD\n",
    "    betaD   = ixp.zerorank1()\n",
    "    gammaDD = ixp.zerorank2()\n",
    "    for i in range(3):\n",
    "        betaD[i] = g4DD[0][i]\n",
    "        for j in range(3):\n",
    "            gammaDD[i][j] = g4DD[i+1][j+1]\n",
    "\n",
    "    # Step 3: Compute betaU\n",
    "    # Step 3.a: Compute gammaUU based on provided gammaDD\n",
    "    gammaUU, _gammaDET = ixp.symm_matrix_inverter3x3(gammaDD)\n",
    "\n",
    "    # Step 3.b: Use gammaUU to raise betaU\n",
    "    betaU = ixp.zerorank1()\n",
    "    for i in range(3):\n",
    "        for j in range(3):\n",
    "            betaU[i] += gammaUU[i][j]*betaD[j]\n",
    "\n",
    "    # Step 4:   Compute alpha = sqrt(beta^2 - g_{00}):\n",
    "    # Step 4.a: Compute beta^2 = beta^k beta_k:\n",
    "    beta_squared = sp.sympify(0)\n",
    "    for k in range(3):\n",
    "        beta_squared += betaU[k]*betaD[k]\n",
    "\n",
    "    # Step 4.b: alpha = sqrt(beta^2 - g_{00}):\n",
    "    alpha = sp.sqrt(sp.simplify(beta_squared) - g4DD[0][0])\n",
    "\n",
    "    # Step 5: If inputvars == \"ADM\", we are finished. Return.\n",
    "    if inputvars == \"ADM\":\n",
    "        return\n",
    "\n",
    "    # Step 6: If inputvars == \"BSSN\", convert ADM to BSSN & return hDD, cf,\n",
    "    import BSSN.BSSN_in_terms_of_ADM as BitoA\n",
    "    dummyBU = ixp.zerorank1()\n",
    "    BitoA.gammabarDD_hDD( gammaDD)\n",
    "    BitoA.cf_from_gammaDD(gammaDD)\n",
    "    BitoA.betU_vetU(      betaU,dummyBU)\n",
    "    hDD  = BitoA.hDD\n",
    "    cf   = BitoA.cf\n",
    "    vetU = BitoA.vetU"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='adm_ito_fourmetric_validate'></a>\n",
    "\n",
    "## Step 3.a: ADM in terms of 4-metric validation: Confirm $\\gamma_{ij}\\gamma^{ij}=3$  \\[Back to [top](#toc)\\]\n",
    "$$\\label{adm_ito_fourmetric_validate}$$\n",
    "\n",
    "Next we compute $\\gamma^{ij} \\gamma_{ij}$ as a validation check. It should equal 3:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:04:55.889436Z",
     "iopub.status.busy": "2021-03-07T17:04:55.853637Z",
     "iopub.status.idle": "2021-03-07T17:04:56.239195Z",
     "shell.execute_reply": "2021-03-07T17:04:56.239674Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TEST PASSED!\n"
     ]
    }
   ],
   "source": [
    "BSSN_or_ADM_ito_g4DD(\"ADM\")\n",
    "gammaUU, gammaDET = ixp.symm_matrix_inverter3x3(gammaDD)\n",
    "\n",
    "contraction = sp.sympify(0)\n",
    "for i in range(3):\n",
    "    for j in range(3):\n",
    "        contraction += gammaDD[i][j]*gammaUU[i][j]\n",
    "if sp.simplify(contraction) == sp.sympify(3):\n",
    "    print(\"TEST PASSED!\")\n",
    "else:\n",
    "    print(\"TEST FAILED: \"+str(contraction)+\" does not apparently equal 3.\")\n",
    "    sys.exit(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='bssn_ito_fourmetric_validate'></a>\n",
    "\n",
    "## Step 3.b: BSSN in terms of 4-metric validation: Confirm $\\bar{\\gamma}_{ij}\\bar{\\gamma}^{ij}=3$  \\[Back to [top](#toc)\\]\n",
    "$$\\label{bssn_ito_fourmetric_validate}$$\n",
    "\n",
    "Next we compute $\\bar{\\gamma}_{ij}\\bar{\\gamma}^{ij}$ as a validation check. It should equal 3:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:04:56.314333Z",
     "iopub.status.busy": "2021-03-07T17:04:56.278451Z",
     "iopub.status.idle": "2021-03-07T17:05:00.367571Z",
     "shell.execute_reply": "2021-03-07T17:05:00.366908Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TEST PASSED!\n"
     ]
    }
   ],
   "source": [
    "import reference_metric as rfm\n",
    "par.set_parval_from_str(\"reference_metric::CoordSystem\",\"SinhCylindrical\")\n",
    "rfm.reference_metric()\n",
    "\n",
    "BSSN_or_ADM_ito_g4DD(\"BSSN\")\n",
    "gammabarDD = ixp.zerorank2()\n",
    "for i in range(3):\n",
    "    for j in range(3):\n",
    "        # gammabar_{ij}  = h_{ij}*ReDD[i][j] + gammahat_{ij}\n",
    "        gammabarDD[i][j] = hDD[i][j] * rfm.ReDD[i][j] + rfm.ghatDD[i][j]\n",
    "\n",
    "gammabarUU, gammabarDET = ixp.symm_matrix_inverter3x3(gammabarDD)\n",
    "\n",
    "contraction = sp.sympify(0)\n",
    "for i in range(3):\n",
    "    for j in range(3):\n",
    "        contraction += gammabarDD[i][j]*gammabarUU[i][j]\n",
    "if sp.simplify(contraction) == sp.sympify(3):\n",
    "    print(\"TEST PASSED!\")\n",
    "else:\n",
    "    print(\"TEST FAILED: \"+str(contraction)+\" does not apparently equal 3.\")\n",
    "    sys.exit(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='code_validation'></a>\n",
    "\n",
    "## Step 4: Code Validation against `BSSN.ADMBSSN_tofrom_4metric` NRPy+ module \\[Back to [top](#toc)\\]\n",
    "$$\\label{code_validation}$$\n",
    "\n",
    "Here, as a code validation check, we verify agreement in the SymPy expressions for BrillLindquist initial data between\n",
    "1. this tutorial and \n",
    "2. the NRPy+ [BSSN.ADMBSSN_tofrom_4metric](../edit/BSSN/ADMBSSN_tofrom_4metric.py) module.\n",
    "\n",
    "By default, we analyze these expressions in SinhCylindrical coordinates, though other coordinate systems may be chosen."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:05:00.432621Z",
     "iopub.status.busy": "2021-03-07T17:05:00.401943Z",
     "iopub.status.idle": "2021-03-07T17:05:04.663656Z",
     "shell.execute_reply": "2021-03-07T17:05:04.664220Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BSSN input: g4DD[0][0] - g4DD_mod[0][0] = 0\n",
      "BSSN input: g4DD[0][1] - g4DD_mod[0][1] = 0\n",
      "BSSN input: g4DD[0][2] - g4DD_mod[0][2] = 0\n",
      "BSSN input: g4DD[0][3] - g4DD_mod[0][3] = 0\n",
      "BSSN input: g4DD[1][0] - g4DD_mod[1][0] = 0\n",
      "BSSN input: g4DD[1][1] - g4DD_mod[1][1] = 0\n",
      "BSSN input: g4DD[1][2] - g4DD_mod[1][2] = 0\n",
      "BSSN input: g4DD[1][3] - g4DD_mod[1][3] = 0\n",
      "BSSN input: g4DD[2][0] - g4DD_mod[2][0] = 0\n",
      "BSSN input: g4DD[2][1] - g4DD_mod[2][1] = 0\n",
      "BSSN input: g4DD[2][2] - g4DD_mod[2][2] = 0\n",
      "BSSN input: g4DD[2][3] - g4DD_mod[2][3] = 0\n",
      "BSSN input: g4DD[3][0] - g4DD_mod[3][0] = 0\n",
      "BSSN input: g4DD[3][1] - g4DD_mod[3][1] = 0\n",
      "BSSN input: g4DD[3][2] - g4DD_mod[3][2] = 0\n",
      "BSSN input: g4DD[3][3] - g4DD_mod[3][3] = 0\n",
      "BSSN input: g4UU[0][0] - g4UU_mod[0][0] = 0\n",
      "BSSN input: g4UU[0][1] - g4UU_mod[0][1] = 0\n",
      "BSSN input: g4UU[0][2] - g4UU_mod[0][2] = 0\n",
      "BSSN input: g4UU[0][3] - g4UU_mod[0][3] = 0\n",
      "BSSN input: g4UU[1][0] - g4UU_mod[1][0] = 0\n",
      "BSSN input: g4UU[1][1] - g4UU_mod[1][1] = 0\n",
      "BSSN input: g4UU[1][2] - g4UU_mod[1][2] = 0\n",
      "BSSN input: g4UU[1][3] - g4UU_mod[1][3] = 0\n",
      "BSSN input: g4UU[2][0] - g4UU_mod[2][0] = 0\n",
      "BSSN input: g4UU[2][1] - g4UU_mod[2][1] = 0\n",
      "BSSN input: g4UU[2][2] - g4UU_mod[2][2] = 0\n",
      "BSSN input: g4UU[2][3] - g4UU_mod[2][3] = 0\n",
      "BSSN input: g4UU[3][0] - g4UU_mod[3][0] = 0\n",
      "BSSN input: g4UU[3][1] - g4UU_mod[3][1] = 0\n",
      "BSSN input: g4UU[3][2] - g4UU_mod[3][2] = 0\n",
      "BSSN input: g4UU[3][3] - g4UU_mod[3][3] = 0\n",
      "ADM input: g4DD[0][0] - g4DD_mod[0][0] = 0\n",
      "ADM input: g4DD[0][1] - g4DD_mod[0][1] = 0\n",
      "ADM input: g4DD[0][2] - g4DD_mod[0][2] = 0\n",
      "ADM input: g4DD[0][3] - g4DD_mod[0][3] = 0\n",
      "ADM input: g4DD[1][0] - g4DD_mod[1][0] = 0\n",
      "ADM input: g4DD[1][1] - g4DD_mod[1][1] = 0\n",
      "ADM input: g4DD[1][2] - g4DD_mod[1][2] = 0\n",
      "ADM input: g4DD[1][3] - g4DD_mod[1][3] = 0\n",
      "ADM input: g4DD[2][0] - g4DD_mod[2][0] = 0\n",
      "ADM input: g4DD[2][1] - g4DD_mod[2][1] = 0\n",
      "ADM input: g4DD[2][2] - g4DD_mod[2][2] = 0\n",
      "ADM input: g4DD[2][3] - g4DD_mod[2][3] = 0\n",
      "ADM input: g4DD[3][0] - g4DD_mod[3][0] = 0\n",
      "ADM input: g4DD[3][1] - g4DD_mod[3][1] = 0\n",
      "ADM input: g4DD[3][2] - g4DD_mod[3][2] = 0\n",
      "ADM input: g4DD[3][3] - g4DD_mod[3][3] = 0\n",
      "ADM input: g4UU[0][0] - g4UU_mod[0][0] = 0\n",
      "ADM input: g4UU[0][1] - g4UU_mod[0][1] = 0\n",
      "ADM input: g4UU[0][2] - g4UU_mod[0][2] = 0\n",
      "ADM input: g4UU[0][3] - g4UU_mod[0][3] = 0\n",
      "ADM input: g4UU[1][0] - g4UU_mod[1][0] = 0\n",
      "ADM input: g4UU[1][1] - g4UU_mod[1][1] = 0\n",
      "ADM input: g4UU[1][2] - g4UU_mod[1][2] = 0\n",
      "ADM input: g4UU[1][3] - g4UU_mod[1][3] = 0\n",
      "ADM input: g4UU[2][0] - g4UU_mod[2][0] = 0\n",
      "ADM input: g4UU[2][1] - g4UU_mod[2][1] = 0\n",
      "ADM input: g4UU[2][2] - g4UU_mod[2][2] = 0\n",
      "ADM input: g4UU[2][3] - g4UU_mod[2][3] = 0\n",
      "ADM input: g4UU[3][0] - g4UU_mod[3][0] = 0\n",
      "ADM input: g4UU[3][1] - g4UU_mod[3][1] = 0\n",
      "ADM input: g4UU[3][2] - g4UU_mod[3][2] = 0\n",
      "ADM input: g4UU[3][3] - g4UU_mod[3][3] = 0\n",
      "BSSN QUANTITIES (ito 4-metric g4DD)\n",
      "cf - mod_cf = 0\n",
      "alpha - mod_alpha = 0\n",
      "vetU[0] - mod_vetU[0] = 0\n",
      "hDD[0][0] - mod_hDD[0][0] = 0\n",
      "hDD[0][1] - mod_hDD[0][1] = 0\n",
      "hDD[0][2] - mod_hDD[0][2] = 0\n",
      "vetU[1] - mod_vetU[1] = 0\n",
      "hDD[1][0] - mod_hDD[1][0] = 0\n",
      "hDD[1][1] - mod_hDD[1][1] = 0\n",
      "hDD[1][2] - mod_hDD[1][2] = 0\n",
      "vetU[2] - mod_vetU[2] = 0\n",
      "hDD[2][0] - mod_hDD[2][0] = 0\n",
      "hDD[2][1] - mod_hDD[2][1] = 0\n",
      "hDD[2][2] - mod_hDD[2][2] = 0\n",
      "ADM QUANTITIES (ito 4-metric g4DD)\n",
      "alpha - mod_alpha = 0\n",
      "betaU[0] - mod_betaU[0] = 0\n",
      "gammaDD[0][0] - mod_gammaDD[0][0] = 0\n",
      "gammaDD[0][1] - mod_gammaDD[0][1] = 0\n",
      "gammaDD[0][2] - mod_gammaDD[0][2] = 0\n",
      "betaU[1] - mod_betaU[1] = 0\n",
      "gammaDD[1][0] - mod_gammaDD[1][0] = 0\n",
      "gammaDD[1][1] - mod_gammaDD[1][1] = 0\n",
      "gammaDD[1][2] - mod_gammaDD[1][2] = 0\n",
      "betaU[2] - mod_betaU[2] = 0\n",
      "gammaDD[2][0] - mod_gammaDD[2][0] = 0\n",
      "gammaDD[2][1] - mod_gammaDD[2][1] = 0\n",
      "gammaDD[2][2] - mod_gammaDD[2][2] = 0\n"
     ]
    }
   ],
   "source": [
    "par.set_parval_from_str(\"reference_metric::CoordSystem\",\"SinhCylindrical\")\n",
    "rfm.reference_metric()\n",
    "\n",
    "import BSSN.ADMBSSN_tofrom_4metric as AB4m\n",
    "for inputvars in [\"BSSN\",\"ADM\"]:\n",
    "    g4DD_ito_BSSN_or_ADM(inputvars)\n",
    "    AB4m.g4DD_ito_BSSN_or_ADM(inputvars)\n",
    "    for i in range(4):\n",
    "        for j in range(4):\n",
    "            print(inputvars+\" input: g4DD[\"+str(i)+\"][\"+str(j)+\"] - g4DD_mod[\"+str(i)+\"][\"\n",
    "                  +str(j)+\"] = \"+str(g4DD[i][j]-AB4m.g4DD[i][j]))\n",
    "\n",
    "    g4UU_ito_BSSN_or_ADM(inputvars)\n",
    "    AB4m.g4UU_ito_BSSN_or_ADM(inputvars)\n",
    "    for i in range(4):\n",
    "        for j in range(4):\n",
    "            print(inputvars+\" input: g4UU[\"+str(i)+\"][\"+str(j)+\"] - g4UU_mod[\"+str(i)+\"][\"\n",
    "                  +str(j)+\"] = \"+str(g4UU[i][j]-AB4m.g4UU[i][j]))\n",
    "\n",
    "BSSN_or_ADM_ito_g4DD(\"BSSN\")\n",
    "AB4m.BSSN_or_ADM_ito_g4DD(\"BSSN\")\n",
    "print(\"BSSN QUANTITIES (ito 4-metric g4DD)\")\n",
    "print(\"cf - mod_cf = \" + str(cf - AB4m.cf))\n",
    "print(\"alpha - mod_alpha = \" + str(alpha - AB4m.alpha))\n",
    "for i in range(3):\n",
    "    print(\"vetU[\"+str(i)+\"] - mod_vetU[\"+str(i)+\"] = \" + str(vetU[i] - AB4m.vetU[i]))\n",
    "    for j in range(3):\n",
    "        print(\"hDD[\"+str(i)+\"][\"+str(j)+\"] - mod_hDD[\"+str(i)+\"][\"+str(j)+\"] = \"\n",
    "              + str(hDD[i][j] - AB4m.hDD[i][j]))\n",
    "\n",
    "BSSN_or_ADM_ito_g4DD(\"ADM\")\n",
    "AB4m.BSSN_or_ADM_ito_g4DD(\"ADM\")\n",
    "print(\"ADM QUANTITIES (ito 4-metric g4DD)\")\n",
    "print(\"alpha - mod_alpha = \" + str(alpha - AB4m.alpha))\n",
    "for i in range(3):\n",
    "    print(\"betaU[\"+str(i)+\"] - mod_betaU[\"+str(i)+\"] = \" + str(betaU[i] - AB4m.betaU[i]))\n",
    "    for j in range(3):\n",
    "        print(\"gammaDD[\"+str(i)+\"][\"+str(j)+\"] - mod_gammaDD[\"+str(i)+\"][\"+str(j)+\"] = \"\n",
    "              + str(gammaDD[i][j] - AB4m.gammaDD[i][j]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='latex_pdf_output'></a>\n",
    "\n",
    "# Step 4: Output this notebook 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 [Tutorial-ADMBSSN_tofrom_4metric.pdf](Tutorial-ADMBSSN_tofrom_4metric.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": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:05:04.671046Z",
     "iopub.status.busy": "2021-03-07T17:05:04.668211Z",
     "iopub.status.idle": "2021-03-07T17:05:08.160672Z",
     "shell.execute_reply": "2021-03-07T17:05:08.161500Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Created Tutorial-ADMBSSN_tofrom_4metric.tex, and compiled LaTeX file to PDF\n",
      "    file Tutorial-ADMBSSN_tofrom_4metric.pdf\n"
     ]
    }
   ],
   "source": [
    "import cmdline_helper as cmd    # NRPy+: Multi-platform Python command-line interface\n",
    "cmd.output_Jupyter_notebook_to_LaTeXed_PDF(\"Tutorial-ADMBSSN_tofrom_4metric\")"
   ]
  }
 ],
 "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.11.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}