{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "# Formulation of Maxwell's Equations in Cartesian Coordinates and Flat Spacetime - An Overview\n", "\n", "## Author: Terrence Pierre Jacques\n", "\n", "## This tutorial notebook outlines two formulations of Maxwell's equations.\n", "\n", "\n", "### This module serves as a stepping stone towards solving Einstein's equations using NRPy+. As such, the [tutorial notebook on the scalar wave equation in curvilinear coordinates](Tutorial-ScalarWaveCurvilinear.ipynb) is *required* reading before beginning this module. That module, as well as its own prerequisite [module on reference metrics within NRPy+](Tutorial-Reference_Metric.ipynb) provides the needed overview of how NRPy+ handles reference metrics.\n", "\n", "# Introduction \n", "\n", "To numerically solve Einstein's equations--a system of coupled, non-linear equations--the spatial coordinates may be decoupled from the time coordinate. In doing so, numerical solutions may be marched forward in time, using the [Method of Lines](https://reference.wolfram.com/language/tutorial/NDSolveMethodOfLines.html) ([NRPy+ tutorial here](Tutorial-Method_of_Lines-C_Code_Generation.ipynb)). This is done using the 3 + 1 decomposition, originally done using the ADM formalism. However, it was found that using this formulation of Einstein's equations resulted in unstable simulations, due to its weakly hyperbolic system of equations. Hyperbolicity is the notion of the wave-like behavior of the numerical solution for a given system of PDE's. The ADM formulation of Einstein's equations involved mixed second derivatives, which give rise to a weakly hyperbolic system.\n", "\n", "In contrast, the BSSN formalism removes these mixed second derivatives, resulting in a strongly hyperbolic system of equations. In this module, we follow the work of [Knapp, Walker & Baumgarte (2002)](https://arxiv.org/abs/gr-qc/0201051), showcasing the difference between using strongly versus weakly hyperbolic systems, when solving a physical problem with Maxwell's equations in vacuum.\n", " \n", " ### A Note on Notation:\n", "\n", "As is standard in NRPy+, \n", "\n", "* Greek indices refer to four-dimensional quantities where the zeroth component indicates temporal (time) component.\n", "* Latin indices refer to three-dimensional quantities. This is somewhat counterintuitive since Python always indexes its lists starting from 0. As a result, the zeroth component of three-dimensional quantities will necessarily indicate the first *spatial* direction.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "$$\\label{top}$$\n", "\n", "# Table of Contents: \n", "\n", "1. [Step 1](#step1): Maxwell's Equations in Vacuum - System I (ADM-like)\n", "1. [Step 2](#step2): Maxwell's Equations in Vacuum - System II (BSSN-like)\n", "1. [Step 3](#latex_pdf_output): Output this notebook to $\\LaTeX$-formatted PDF file" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Step 1: Maxwell's Equations in Vacuum - System I (ADM-like) \\[Back to [top](#top)\\]\n", "$$\\label{step1}$$\n", "\n", "We begin with Maxwell's equations in vacuum, i.e. no source terms, in flat space and in [Gaussian](https://en.wikipedia.org/wiki/Gaussian_units) and $c = 1$ units, given by \n", "\n", "\\begin{align}\n", "&\\vec{\\nabla} \\cdot \\vec{E} = 0, \\\\\n", "&\\vec{\\nabla} \\cdot \\vec{B} = 0, \\\\\n", "&\\frac{\\partial \\vec{B}}{\\partial t} = -\\vec{\\nabla} \\times \\vec{E}, \\\\\n", "&\\frac{\\partial \\vec{E}}{\\partial t} = \\vec{\\nabla} \\times \\vec{B}.\n", "\\end{align}\n", "\n", "We also have the associated potentials\n", "\n", "\\begin{align}\n", "\\frac{\\partial \\vec{A}}{\\partial t} &= -\\vec{E} -\\vec{\\nabla}\\varphi , \\\\\n", "\\vec{B} &= \\vec{\\nabla} \\times \\vec{A}.\n", "\\end{align}\n", "\n", "Now, replacing $\\vec{B}$ with $\\vec{\\nabla} \\times \\vec{A}$ in Ampere's law, and using the standard identity\n", "\n", "$$\n", "\\vec{\\nabla} \\times \\left( \\vec{\\nabla} \\times \\vec{A} \\right) = \\vec{\\nabla} \\left( \\vec{\\nabla} \\cdot \\vec{A} \\right) - \\nabla^2 \\vec{A},\n", "$$\n", "\n", "we may write\n", "\n", "$$\n", "\\vec{\\nabla} \\times \\vec{B} = \\vec{\\nabla} \\times \\left( \\vec{\\nabla} \\times \\vec{A} \\right) = \\vec{\\nabla} \\left( \\vec{\\nabla} \\cdot \\vec{A} \\right) - \\nabla^2 \\vec{A}.\n", "$$\n", "\n", "Thus, our time evolution equations become\n", "\n", "\\begin{align}\n", "\\frac{\\partial \\vec{A}}{\\partial t} &= -\\vec{E} -\\vec{\\nabla}\\varphi , \\\\\n", "\\frac{\\partial \\vec{E}}{\\partial t} &= \\vec{\\nabla} \\left( \\vec{\\nabla} \\cdot \\vec{A} \\right) - \\nabla^2 \\vec{A}.\n", "\\end{align}\n", "\n", "\n", "Using index notation, in Cartesian coordinates we have \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", "\\end{align}\n", "\n", "Note the presence of the mixed second derivative above, and that in our system of equations we have 6 equations (since $\\vec{A}$ and $\\vec{E}$ each have 3 components), but 7 unknowns (components of $\\vec{A}$ and $\\vec{E}$, and the scalar potential $\\varphi$). Thus, we’ll add a time evolution equation to $\\varphi$ as well, which amounts to choosing a gauge. In particular we’ll choose the [Lorenz gauge](https://en.wikipedia.org/wiki/Lorenz_gauge_condition).\n", "\n", "$$\n", "\\partial_t \\varphi = -\\vec{\\nabla} \\cdot \\vec{A}\n", "$$\n", "\n", "Using index notation, in Cartesian coordinates\n", "\n", "$$\n", "\\partial_t \\varphi = -\\partial_i A^i.\n", "$$\n", "\n", "Furthermore, note that because we are working in vacuum, in Cartesian coordinates we have the constraints\n", "\n", "\\begin{align}\n", "\\partial_i E^i &= 0, \\\\\n", "\\partial_i B^i &= 0.\n", "\\end{align}\n", "\n", "Since $\\vec{B} = \\vec{\\nabla} \\times \\vec{A}$, the divergence of $\\vec{B}$ is automatically satisfied (excercise for the reader).\n", "\n", "The right hand sides (RHSs) of our evolution equations are thus\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}\n", "\n", "subject to the constraint\n", "\n", "$$\n", "\\mathcal{C} \\equiv \\partial_i E^i = 0.\n", "$$\n", "\n", "Tracking the departure of our numerical results from this constraint helps us keep track of the numerical error. We refer to this system of equations as System I.\n", "\n", "In [this tutorial](Tutorial-VacuumMaxwell_Cartesian_RHSs.ipynb) the RHSs and constraint equations are implemented in NRPy+. The system is then evolved in time within a [start-to-finish notebook](Tutorial-Start_to_Finish-Solving_Maxwells_Equations_in_Vacuum-Cartesian.ipynb), using initial data defined in [this tutorial](Tutorial-VacuumMaxwell_InitialData.ipynb), showcasing the **instability** of the system as a result of the presence of the mixed second derivative for $E^i$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Step 2: Maxwell's Equations in Vacuum - System II (BSSN - like) \\[Back to [top](#top)\\]\n", "$$\\label{step2}$$\n", "\n", "As dicussed in the introduction and following the previous section, to maintain numerical stability and accuracy we remove the mixed 2nd derivative $\\partial^i \\partial_j A^j$ in the equation for $E^i$ by introducing\n", "\n", "\\begin{align}\n", "\\Gamma &\\equiv \\partial_i A^i, \\\\\n", "\\partial_t \\Gamma &= \\partial_i \\partial_t A^i = -\\partial_i E^i - \\partial_i \\partial^i \\varphi \\\\\n", " &= - \\partial_i \\partial^i \\varphi.\n", "\\end{align}\n", "\n", "Thus, our evolution equations are \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}\n", "\n", "subject to the constraints\n", "\n", "\\begin{align}\n", "\\mathcal{G} &\\equiv \\Gamma - \\partial_i A^i &= 0, \\\\\n", "\\mathcal{C} &\\equiv \\partial_i E^i &= 0.\n", "\\end{align}\n", "\n", "We refer to this system of equations as System II.\n", "\n", "In [this tutorial](Tutorial-VacuumMaxwell_Cartesian_RHSs.ipynb) the RHSs and constraints are implemented in NRPy+. The system is then evolved in time within a [start-to-finish notebook](Tutorial-Start_to_Finish-Solving_Maxwells_Equations_in_Vacuum-Cartesian.ipynb), using initial data defined in [this tutorial](Tutorial-VacuumMaxwell_InitialData.ipynb), showcasing the **stability** of the system as a result of the absence of the mixed second derivative for $E^i$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Step 3: Output this notebook to $\\LaTeX$-formatted PDF file \\[Back to [top](#top)\\]\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_formulation_Cartesian.pdf](Tutorial-VacuumMaxwell_formulation_Cartesian.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:19:00.566598Z", "iopub.status.busy": "2021-03-07T17:19:00.565431Z", "iopub.status.idle": "2021-03-07T17:19:03.638163Z", "shell.execute_reply": "2021-03-07T17:19:03.638997Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created Tutorial-VacuumMaxwell_formulation_Cartesian.tex, and compiled\n", " LaTeX file to PDF file Tutorial-VacuumMaxwell_formulation_Cartesian.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_formulation_Cartesian\")" ] } ], "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.4" } }, "nbformat": 4, "nbformat_minor": 2 }