{
 "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",
    "# Time Evolution of Maxwell's Equations & Constraints in Flat Spacetime and Cartesian Coordinates\n",
    "\n",
    "## Authors: Terrence Pierre Jacques, Zachariah Etienne and Ian Ruchlin\n",
    "\n",
    "### This module constructs the evolution equations for Maxwell's equations as symbolic (SymPy) expressions, for an electromagnetic field in vacuum, as defined in [Tutorial-VacuumMaxwell_formulation_Cartesian](Tutorial-VacuumMaxwell_formulation_Cartesian.ipynb).\n",
    "\n",
    "**Notebook Status:** <font color='green'><b> Validated </b></font>\n",
    "\n",
    "**Validation Notes:** All expressions generated in this module have been validated.\n",
    "\n",
    "### NRPy+ Source Code for this module: [Maxwell/VacuumMaxwell_Flat_Evol_Cartesian.py](../edit/Maxwell/VacuumMaxwell_Flat_Evol_Cartesian.py)\n",
    "\n",
    "[comment]: <> (Introduction: TODO)\n",
    "\n",
    "This tutorial takes the expressions defined in [Tutorial-VacuumMaxwell_formulation_Cartesian](Tutorial-VacuumMaxwell_formulation_Cartesian.ipynb), and constructs them using NRPy+ in SymPy expressions."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='toc'></a>\n",
    "\n",
    "# Table of Contents\n",
    "$$\\label{toc}$$\n",
    "\n",
    "1. [Step 1](#initializenrpy): Initialize needed Python/NRPy+ modules\n",
    "1. [Step 2](#system1): System 1\n",
    "    1. [Step 2.a](#system1_rhs): Construct evolution equations\n",
    "    1. [Step 2.b](#system1_val): Code Validation\n",
    "1. [Step 3](#system2): System 2\n",
    "    1. [Step 3.a](#system2_rhs): Construct evolution equations\n",
    "    1. [Step 3.b](#system2_val): Code Validation\n",
    "1. [Step 4](#latex_pdf_output): Output this notebook to $\\LaTeX$-formatted PDF file"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='initializenrpy'></a>\n",
    "\n",
    "# Step 1: Initialize needed Python/NRPy+ modules \\[Back to [top](#toc)\\]\n",
    "\n",
    "$$\\label{initializenrpy}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:46.283741Z",
     "iopub.status.busy": "2021-03-07T17:18:46.282357Z",
     "iopub.status.idle": "2021-03-07T17:18:46.626517Z",
     "shell.execute_reply": "2021-03-07T17:18:46.624947Z"
    }
   },
   "outputs": [],
   "source": [
    "# Import needed Python modules\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 grid as gri               # NRPy+: Functions having to do with numerical grids\n",
    "\n",
    "#Step 0: Set the spatial dimension parameter to 3.\n",
    "par.set_parval_from_str(\"grid::DIM\", 3)\n",
    "DIM = par.parval_from_str(\"grid::DIM\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='system1'></a>\n",
    "\n",
    "# Step 2: System I \\[Back to [top](#toc)\\]\n",
    "$$\\label{system1}$$\n",
    "\n",
    "<a id='system1_rhs'></a>\n",
    "\n",
    "## Step 2.a: Construct evolution equations \\[Back to [top](#toc)\\]\n",
    "$$\\label{system1_rhs}$$\n",
    "\n",
    "Following our derivations in [Tutorial-VacuumMaxwell_formulation_Cartesian](Tutorial-VacuumMaxwell_formulation_Cartesian.ipynb), we construct the system of equations for System I, in flat space and cartesian coordinates:\n",
    "\n",
    "\\begin{align}\n",
    "\\partial_t A^i &= -E^i - \\partial^i \\varphi, \\\\\n",
    "\\partial_t E^i &= \\partial^i \\partial_j A^j - \\partial_j \\partial^j A^i, \\\\\n",
    "\\partial_t \\varphi &= -\\partial_i A^i,\n",
    "\\end{align}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:46.640662Z",
     "iopub.status.busy": "2021-03-07T17:18:46.639972Z",
     "iopub.status.idle": "2021-03-07T17:18:46.643096Z",
     "shell.execute_reply": "2021-03-07T17:18:46.642537Z"
    }
   },
   "outputs": [],
   "source": [
    "# Register gridfunctions that are needed as input.\n",
    "\n",
    "#  Declare the rank-1 indexed expressions E_{i}, A_{i},\n",
    "#  and \\partial_{i} \\psi, that are to be evolved in time.\n",
    "#  Derivative variables like these must have an underscore\n",
    "#  in them, so the finite difference module can parse\n",
    "#  the variable name properly.\n",
    "\n",
    "# E_i\n",
    "EU = ixp.register_gridfunctions_for_single_rank1(\"EVOL\", \"EU\")\n",
    "\n",
    "# A_i, _AD is unused\n",
    "_AU = ixp.register_gridfunctions_for_single_rank1(\"EVOL\", \"AU\")\n",
    "\n",
    "# \\psi is a scalar function that is time evolved\n",
    "# _psi is unused\n",
    "_psi = gri.register_gridfunctions(\"EVOL\", [\"psi\"])\n",
    "\n",
    "# \\partial_i \\psi\n",
    "psi_dD = ixp.declarerank1(\"psi_dD\")\n",
    "\n",
    "# \\partial_k ( A_i ) --> rank two tensor\n",
    "AU_dD = ixp.declarerank2(\"AU_dD\", \"nosym\")\n",
    "\n",
    "# \\partial_k partial_m ( A_i ) --> rank three tensor\n",
    "AU_dDD = ixp.declarerank3(\"AU_dDD\", \"sym12\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\\begin{align}\n",
    "\\partial_t A^i &= -E^i - \\partial^i \\varphi, \\\\\n",
    "\\partial_t E^i &= \\partial^i \\partial_j A^j - \\partial_j \\partial^j A^i, \\\\\n",
    "\\partial_t \\varphi &= -\\partial_i A^i,\n",
    "\\end{align}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:46.652659Z",
     "iopub.status.busy": "2021-03-07T17:18:46.652026Z",
     "iopub.status.idle": "2021-03-07T17:18:46.695917Z",
     "shell.execute_reply": "2021-03-07T17:18:46.696401Z"
    }
   },
   "outputs": [],
   "source": [
    "# \\partial_t \\psi = -\\partial_i A_i\n",
    "psi_rhs = 0\n",
    "\n",
    "# \\partial_t A_i = E_i - \\partial_i \\psi\n",
    "ArhsU = ixp.zerorank1()\n",
    "\n",
    "# \\partial_t E_i = -\\partial_j^2 A_i + \\partial_j \\partial_i A_j\n",
    "ErhsU = ixp.zerorank1()\n",
    "\n",
    "# RHSs - equations 10 and 11 from https://arxiv.org/abs/gr-qc/0201051\n",
    "for i in range(DIM):\n",
    "    ArhsU[i] = -EU[i] - psi_dD[i]\n",
    "    psi_rhs += -AU_dD[i][i]\n",
    "    for j in range(DIM):\n",
    "        ErhsU[i] += -AU_dDD[i][j][j] + AU_dDD[j][j][i]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Constraint:\n",
    "\n",
    "\\begin{align}\n",
    "\\mathcal{C} \\equiv \\partial_i E^i\n",
    "\\end{align}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:46.701977Z",
     "iopub.status.busy": "2021-03-07T17:18:46.701330Z",
     "iopub.status.idle": "2021-03-07T17:18:46.703484Z",
     "shell.execute_reply": "2021-03-07T17:18:46.703946Z"
    }
   },
   "outputs": [],
   "source": [
    "# \\partial_k ( E^i ) --> rank two tensor\n",
    "EU_dD = ixp.declarerank2(\"EU_dD\", \"nosym\")\n",
    "\n",
    "# C = \\partial_i E^i\n",
    "C = EU_dD[0][0] + EU_dD[1][1] + EU_dD[2][2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:46.715265Z",
     "iopub.status.busy": "2021-03-07T17:18:46.714431Z",
     "iopub.status.idle": "2021-03-07T17:18:46.718545Z",
     "shell.execute_reply": "2021-03-07T17:18:46.719052Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C =  EU_dD00 + EU_dD11 + EU_dD22\n",
      "ArhsU[0] =  -EU0 - psi_dD0\n",
      "ArhsU[1] =  -EU1 - psi_dD1\n",
      "ArhsU[2] =  -EU2 - psi_dD2\n",
      "ErhsU[0] =  -AU_dDD011 - AU_dDD022 + AU_dDD101 + AU_dDD202\n",
      "ErhsU[1] =  AU_dDD001 - AU_dDD100 - AU_dDD122 + AU_dDD212\n",
      "ErhsU[2] =  AU_dDD002 + AU_dDD112 - AU_dDD200 - AU_dDD211\n",
      "psi_rhs  =  -AU_dD00 - AU_dD11 - AU_dD22\n"
     ]
    }
   ],
   "source": [
    "print('C = ', C)\n",
    "print('ArhsU[0] = ', ArhsU[0])\n",
    "print('ArhsU[1] = ', ArhsU[1])\n",
    "print('ArhsU[2] = ', ArhsU[2])\n",
    "print('ErhsU[0] = ', ErhsU[0])\n",
    "print('ErhsU[1] = ', ErhsU[1])\n",
    "print('ErhsU[2] = ', ErhsU[2])\n",
    "print('psi_rhs  = ', psi_rhs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='system1_val'></a>\n",
    "\n",
    "## Step 2.b: NRPy+ Module Code Validation \\[Back to [top](#toc)\\]\n",
    "$$\\label{system1_val}$$\n",
    "\n",
    "Here, as a code validation check, we verify agreement in the SymPy expressions for the RHSs of Maxwell's equations (in System I) between\n",
    "1. this tutorial and \n",
    "2. the NRPy+ [Maxwell/VacuumMaxwell_Flat_Evol_Cartesian.py](../edit/Maxwell/VacuumMaxwell_Flat_Evol_Cartesian.py) module.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:46.726534Z",
     "iopub.status.busy": "2021-03-07T17:18:46.725819Z",
     "iopub.status.idle": "2021-03-07T17:18:47.162628Z",
     "shell.execute_reply": "2021-03-07T17:18:47.163113Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Currently using System_I RHSs \n",
      "\n",
      "Consistency check between Tutorial-VacuumMaxwell_Cartesian_RHSs tutorial and NRPy+ module: ALL SHOULD BE ZERO.\n",
      "C - mwevol.C = 0\n",
      "psi_rhs - mwevol.psi_rhs = 0\n",
      "ArhsU[0] - mwevol.ArhsU[0] = 0\n",
      "ErhsU[0] - mwevol.ErhsU[0] = 0\n",
      "ArhsU[1] - mwevol.ArhsU[1] = 0\n",
      "ErhsU[1] - mwevol.ErhsU[1] = 0\n",
      "ArhsU[2] - mwevol.ArhsU[2] = 0\n",
      "ErhsU[2] - mwevol.ErhsU[2] = 0\n"
     ]
    }
   ],
   "source": [
    "# Reset the list of gridfunctions, as registering a gridfunction\n",
    "#   twice will spawn an error.\n",
    "gri.glb_gridfcs_list = []\n",
    "\n",
    "#          Call the VacuumMaxwellRHSs() function from within the\n",
    "#          Maxwell/VacuumMaxwell_Flat_Evol_Cartesian.py module,\n",
    "#          which should do exactly the same as the steps above.\n",
    "\n",
    "# Set which system to use, which are defined in Maxwell/InitialData.py\n",
    "par.initialize_param(par.glb_param(\"char\", \"Maxwell.InitialData\",\"System_to_use\",\"System_I\"))\n",
    "\n",
    "import Maxwell.VacuumMaxwell_Flat_Evol_Cartesian as mwevol\n",
    "mwevol.VacuumMaxwellRHSs()\n",
    "\n",
    "print(\"Consistency check between Tutorial-VacuumMaxwell_Cartesian_RHSs tutorial and NRPy+ module: ALL SHOULD BE ZERO.\")\n",
    "\n",
    "print(\"C - mwevol.C = \" + str(C - mwevol.C))\n",
    "print(\"psi_rhs - mwevol.psi_rhs = \" + str(psi_rhs - mwevol.psi_rhs))\n",
    "for i in range(DIM):\n",
    "\n",
    "    print(\"ArhsU[\"+str(i)+\"] - mwevol.ArhsU[\"+str(i)+\"] = \" + str(ArhsU[i] - mwevol.ArhsU[i]))\n",
    "    print(\"ErhsU[\"+str(i)+\"] - mwevol.ErhsU[\"+str(i)+\"] = \" + str(ErhsU[i] - mwevol.ErhsU[i]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='system2'></a>\n",
    "\n",
    "# Step 3: System II \\[Back to [top](#toc)\\]\n",
    "$$\\label{system2}$$\n",
    "\n",
    "<a id='system2_rhs'></a>\n",
    "\n",
    "## Step 3.a: Construct evolution equations \\[Back to [top](#toc)\\]\n",
    "$$\\label{system2_rhs}$$\n",
    "\n",
    "Next, again following [Tutorial-VacuumMaxwell_formulation_Cartesian](Tutorial-VacuumMaxwell_formulation_Cartesian.ipynb), we construct the system of equations for System II, in flat space and cartesian coordinates:\n",
    "\n",
    "\\begin{align}\n",
    "\\partial_t A^i &= -E^i - \\partial^i \\varphi, \\\\\n",
    "\\partial_t E^i &= \\partial^i \\Gamma - \\partial_j \\partial^j A^i, \\\\\n",
    "\\partial_t \\Gamma &= - \\partial_i \\partial^i \\varphi, \\\\\n",
    "\\partial_t \\varphi &= -\\Gamma,\n",
    "\\end{align}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:47.173619Z",
     "iopub.status.busy": "2021-03-07T17:18:47.172518Z",
     "iopub.status.idle": "2021-03-07T17:18:47.176231Z",
     "shell.execute_reply": "2021-03-07T17:18:47.177083Z"
    }
   },
   "outputs": [],
   "source": [
    "# We inherit here all of the definitions from System I, above\n",
    "\n",
    "# Register the scalar auxiliary variable \\Gamma\n",
    "Gamma = gri.register_gridfunctions(\"EVOL\", [\"Gamma\"])\n",
    "\n",
    "# Declare the ordinary gradient \\partial_{i} \\Gamma\n",
    "Gamma_dD = ixp.declarerank1(\"Gamma_dD\")\n",
    "\n",
    "# partial_i \\partial_j \\psi\n",
    "psi_dDD = ixp.declarerank2(\"psi_dDD\", \"sym01\")\n",
    "\n",
    "psi_rhs = -Gamma"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\\begin{align}\n",
    "\\partial_t A^i &= -E^i - \\partial^i \\varphi, \\\\\n",
    "\\partial_t E^i &= \\partial^i \\Gamma - \\partial_j \\partial^j A^i, \\\\\n",
    "\\partial_t \\Gamma &= - \\partial_i \\partial^i \\varphi, \\\\\n",
    "\\partial_t \\varphi &= -\\Gamma,\n",
    "\\end{align}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:47.190722Z",
     "iopub.status.busy": "2021-03-07T17:18:47.189928Z",
     "iopub.status.idle": "2021-03-07T17:18:47.192137Z",
     "shell.execute_reply": "2021-03-07T17:18:47.192609Z"
    }
   },
   "outputs": [],
   "source": [
    "# Equation 15 https://arxiv.org/abs/gr-qc/0201051\n",
    "# \\partial_t \\Gamma = -\\partial_i^2 \\psi\n",
    "Gamma_rhs = 0\n",
    "\n",
    "# \\partial_t A_i = -E_i - \\partial_i \\psi\n",
    "ArhsU = ixp.zerorank1()\n",
    "\n",
    "# \\partial_t E_i = -\\partial_j^2 A_i + \\partial_i \\Gamma\n",
    "ErhsU = ixp.zerorank1()\n",
    "\n",
    "# RHSs - equations 10 and 14 https://arxiv.org/abs/gr-qc/0201051\n",
    "for i in range(DIM):\n",
    "    ArhsU[i] = -EU[i] - psi_dD[i]\n",
    "    Gamma_rhs -= psi_dDD[i][i]\n",
    "    ErhsU[i] += Gamma_dD[i]\n",
    "    for j in range(DIM):\n",
    "        ErhsU[i] -= AU_dDD[i][j][j]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Constraints:\n",
    "\n",
    "\\begin{align}\n",
    "\\mathcal{G} &\\equiv \\Gamma - \\partial_i A^i, \\\\\n",
    "\\mathcal{C} &\\equiv \\partial_i E^i.\n",
    "\\end{align}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:47.200830Z",
     "iopub.status.busy": "2021-03-07T17:18:47.199752Z",
     "iopub.status.idle": "2021-03-07T17:18:47.204835Z",
     "shell.execute_reply": "2021-03-07T17:18:47.205386Z"
    }
   },
   "outputs": [],
   "source": [
    "# \\partial_k ( E^i ) --> rank two tensor\n",
    "EU_dD = ixp.declarerank2(\"EU_dD\", \"nosym\")\n",
    "\n",
    "# C = \\partial_i E^i\n",
    "C = EU_dD[0][0] + EU_dD[1][1] + EU_dD[2][2]\n",
    "\n",
    "# G = \\Gamma - \\partial_i A^i\n",
    "G = Gamma - AU_dD[0][0] - AU_dD[1][1] - AU_dD[2][2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:47.216491Z",
     "iopub.status.busy": "2021-03-07T17:18:47.215710Z",
     "iopub.status.idle": "2021-03-07T17:18:47.221227Z",
     "shell.execute_reply": "2021-03-07T17:18:47.220653Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C =  EU_dD00 + EU_dD11 + EU_dD22\n",
      "G =  -AU_dD00 - AU_dD11 - AU_dD22 + Gamma\n",
      "ArhsU[0]  =  -EU0 - psi_dD0\n",
      "ArhsU[1]  =  -EU1 - psi_dD1\n",
      "ArhsU[2]  =  -EU2 - psi_dD2\n",
      "ErhsU[0]  =  -AU_dDD000 - AU_dDD011 - AU_dDD022 + Gamma_dD0\n",
      "ErhsU[1]  =  -AU_dDD100 - AU_dDD111 - AU_dDD122 + Gamma_dD1\n",
      "ErhsU[2]  =  -AU_dDD200 - AU_dDD211 - AU_dDD222 + Gamma_dD2\n",
      "psi_rhs   =  -Gamma\n",
      "Gamma_rhs = -psi_dDD00 - psi_dDD11 - psi_dDD22\n"
     ]
    }
   ],
   "source": [
    "print('C = ', C)\n",
    "print('G = ', G)\n",
    "print('ArhsU[0]  = ', ArhsU[0])\n",
    "print('ArhsU[1]  = ', ArhsU[1])\n",
    "print('ArhsU[2]  = ', ArhsU[2])\n",
    "print('ErhsU[0]  = ', ErhsU[0])\n",
    "print('ErhsU[1]  = ', ErhsU[1])\n",
    "print('ErhsU[2]  = ', ErhsU[2])\n",
    "print('psi_rhs   = ', psi_rhs)\n",
    "print('Gamma_rhs =', Gamma_rhs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='system2_val'></a>\n",
    "\n",
    "## Step 3.b: NRPy+ Module Code Validation \\[Back to [top](#toc)\\]\n",
    "$$\\label{system2_val}$$\n",
    "\n",
    "Here, as a code validation check, we verify agreement in the SymPy expressions for the RHSs of Maxwell's equations (in System II) between\n",
    "1. this tutorial and \n",
    "2. the NRPy+ [Maxwell/VacuumMaxwell_Flat_Evol_Cartesian.py](../edit/Maxwell/VacuumMaxwell_Flat_Evol_Cartesian.py) module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:47.290416Z",
     "iopub.status.busy": "2021-03-07T17:18:47.254631Z",
     "iopub.status.idle": "2021-03-07T17:18:47.299468Z",
     "shell.execute_reply": "2021-03-07T17:18:47.299993Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Currently using System_II RHSs \n",
      "\n",
      "Consistency check between Tutorial-VacuumMaxwell_Cartesian_RHSs tutorial and NRPy+ module: ALL SHOULD BE ZERO.\n",
      "C - mwevol.C = 0\n",
      "G - mwevol.G = 0\n",
      "psi_rhs - mwevol.psi_rhs = 0\n",
      "Gamma_rhs - mwevol.Gamma_rhs = 0\n",
      "ArhsU[0] - mwevol.ArhsU[0] = 0\n",
      "ErhsU[0] - mwevol.ErhsU[0] = 0\n",
      "ArhsU[1] - mwevol.ArhsU[1] = 0\n",
      "ErhsU[1] - mwevol.ErhsU[1] = 0\n",
      "ArhsU[2] - mwevol.ArhsU[2] = 0\n",
      "ErhsU[2] - mwevol.ErhsU[2] = 0\n"
     ]
    }
   ],
   "source": [
    "# Reset the list of gridfunctions, as registering a gridfunction\n",
    "#   twice will spawn an error.\n",
    "gri.glb_gridfcs_list = []\n",
    "\n",
    "#          Call the VacuumMaxwellRHSs() function from within the\n",
    "#          Maxwell/VacuumMaxwell_Flat_Evol_Cartesian.py module,\n",
    "#          which should do exactly the same as the steps above.\n",
    "\n",
    "par.set_paramsvals_value(\"Maxwell.InitialData::System_to_use=System_II\")\n",
    "mwevol.VacuumMaxwellRHSs()\n",
    "\n",
    "print(\"Consistency check between Tutorial-VacuumMaxwell_Cartesian_RHSs tutorial and NRPy+ module: ALL SHOULD BE ZERO.\")\n",
    "\n",
    "print(\"C - mwevol.C = \" + str(C - mwevol.C))\n",
    "print(\"G - mwevol.G = \" + str(G - mwevol.G))\n",
    "print(\"psi_rhs - mwevol.psi_rhs = \" + str(psi_rhs - mwevol.psi_rhs))\n",
    "print(\"Gamma_rhs - mwevol.Gamma_rhs = \" + str(Gamma_rhs - mwevol.Gamma_rhs))\n",
    "for i in range(DIM):\n",
    "\n",
    "    print(\"ArhsU[\"+str(i)+\"] - mwevol.ArhsU[\"+str(i)+\"] = \" + str(ArhsU[i] - mwevol.ArhsU[i]))\n",
    "    print(\"ErhsU[\"+str(i)+\"] - mwevol.ErhsU[\"+str(i)+\"] = \" + str(ErhsU[i] - mwevol.ErhsU[i]))"
   ]
  },
  {
   "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\n",
    "[Tutorial-VacuumMaxwell_Cartesian_RHSs.pdf](Tutorial-VacuumMaxwell_Cartesian_RHSs.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": 12,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:18:47.304599Z",
     "iopub.status.busy": "2021-03-07T17:18:47.303930Z",
     "iopub.status.idle": "2021-03-07T17:18:51.178598Z",
     "shell.execute_reply": "2021-03-07T17:18:51.179321Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Created Tutorial-VacuumMaxwell_Cartesian_RHSs.tex, and compiled LaTeX file\n",
      "    to PDF file Tutorial-VacuumMaxwell_Cartesian_RHSs.pdf\n"
     ]
    }
   ],
   "source": [
    "import cmdline_helper as cmd    # NRPy+: Multi-platform Python command-line interface\n",
    "cmd.output_Jupyter_notebook_to_LaTeXed_PDF(\"Tutorial-VacuumMaxwell_Cartesian_RHSs\")"
   ]
  }
 ],
 "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.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}