{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "# Formulation of Maxwell's Equations in Curvilinear Coordinates and Flat Spacetime- An Overview\n", "\n", "## Author: Terrence Pierre Jacques\n", "\n", "## This tutorial notebook constructs Maxwell's equations in a covariant form.\n", "\n", "\n", "### This module follows from the derivations of [Tutorial-VacuumMaxwell_formulation_Cartesian](Tutorial-VacuumMaxwell_formulation_Cartesian.ipynb).\n", "\n", "# Introduction \n", "\n", "Following [Tutorial-VacuumMaxwell_formulation_Cartesian](Tutorial-VacuumMaxwell_formulation_Cartesian.ipynb) and [Tutorial-Start_to_Finish-Solving_Maxwells_Equations_in_Vacuum-Cartesian notebook](Tutorial-Start_to_Finish-Solving_Maxwells_Equations_in_Vacuum-Cartesian.ipynb), the user will note that solving the system of equations seems computationally wasteful. The toroidal dipole field initial data as implemented in [this tutorial](Tutorial-VacuumMaxwell_InitialData.ipynb) are axisymmetric, so one hardly needs to sample the numerical solution in the $\\phi$ direction. Thus, the numerical solution requires sampling in the $r$ and $\\theta$ directions. Therefore, evolving these initial data in Cartesian coordinates is wasteful, as we do not take advantages of the symmetry of the problem. To do so, we must evolve the system in spherical or cylindrical like coordinate systems, or curvilinear coordinate systems. However, we must then reformulate Maxwell's equations into a covariant form.\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](#step3): Maxwell's Equations in Vacuum and Curvilinear Coordinates\n", " 1. [Step 1.a](#step3a): System II in Curvilinear Coordinates\n", " 1. [Step 1.b](#step3b): System II in Curvilinear Coordinates, using the rescaled quantities $a^i$ and $e^i$\n", "1. [Step 2](#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 and Curvilinear Coordinates \\[Back to [top](#top)\\]\n", "$$\\label{step3}$$\n", "\n", "\n", "\n", "## Step 1a: System II (BSSN - like) in Curvilinear Coordinates \\[Back to [top](#top)\\]\n", "$$\\label{step3a}$$\n", "\n", "Our current formulation of Maxwell's equations remains non-covariant, i.e. the forms of the equations will be altered if we move to curvilinear coordinates. To address this issue, and thus allow us to write the equations down in any arbitrary coordinate system, we must rewrite the equations to be manifestly covariant. \n", "\n", "We begin this process by employing the so-called \"comma goes to semi-colon rule,\" replacing all partial derivatives, which do not transform as tensorial quantities, with covariant derivatives, which do. Rewriting Maxwell's equations with only tensorial quantities will yield a covariant formulation of the equations. So, starting with System II in [this tutorial](Tutorial-VacuumMaxwell_formulation_Cartesian.ipynb),\n", "\n", "\\begin{align}\n", "\\partial_t A^i = -E^i - \\partial^i \\varphi &\\to -E^i - \\hat{\\nabla}^i \\varphi = -E^i - \\hat{g}^{ij}\\hat{\\nabla}_j \\varphi, \\\\\n", "\\partial_t E^i = \\partial^i \\Gamma - \\partial_j \\partial^j A^i &\\to \\hat{\\nabla}^i \\Gamma - \\hat{\\nabla} _j \\hat{\\nabla}^j A^i = \\hat{g}^{ij}\\hat{\\nabla}_j \\Gamma - \\hat{g}^{jk}\\hat{\\nabla}_j \\hat{\\nabla}_k A^i, \\\\\n", "\\partial_t \\Gamma = - \\partial_i \\partial^i \\varphi &\\to - \\hat{\\nabla}_i \\hat{\\nabla}^i \\varphi = - \\hat{g}^{ij}\\hat{\\nabla}_i \\hat{\\nabla}_j \\varphi, \\\\\n", "\\partial_t \\varphi = -\\Gamma,\n", "\\end{align}\n", "\n", "where $\\hat{\\nabla}_i$ is the [covariant derivative](https://en.wikipedia.org/wiki/Covariant_derivative) associated with the reference metric $\\hat{g}_{ij}$ which describes a flat space background, in an arbitrary coordinate system. Expanding the above equations using the standard covariant derivative definitions, we arrive at\n", "\n", "\\begin{align}\n", "\\partial_t A^i &= -E^i - \\hat{g}^{ij}\\partial_j \\varphi, \\\\\n", "\\partial_t E^i &= \\hat{g}^{ij}\\partial_j \\Gamma - \\hat{g}^{jk}\\hat{\\nabla}_j \\hat{\\nabla}_k A^i, \\\\\n", "\\partial_t \\Gamma &= -\\hat{g}^{ij} \\left( \\partial_i \\partial_j \\varphi - \\hat{\\Gamma}^k_{ji} \\partial_k \\varphi \\right), \\\\\n", "\\partial_t \\varphi &= -\\Gamma,\n", "\\end{align}\n", "\n", "\n", "and subject to constraints\n", "\n", "\\begin{align}\n", "\\mathcal{G} &\\equiv \\Gamma - \\partial_i A^i - \\hat{\\Gamma}^i_{ji} A^j &= 0,\\\\\n", "\\mathcal{C} &\\equiv \\partial_i E^i + \\hat{\\Gamma}^i_{ji} E^j &= 0,\n", "\\end{align}\n", "\n", "where $\\hat{\\Gamma}^i _{jk}$ is the metric connection associated with $\\hat{g}_{ij}$.\n", "\n", "In the cell below we expand the covariant laplacian within the evolution equation for $E^i$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Based on the definition of the covariant derivative, we have\n", "$$\n", "\\hat{\\nabla}_{k} A^{i} = A^i_{,k} + \\hat{\\Gamma}^i_{mk} A^m\n", "$$\n", "\n", "Since $\\hat{\\nabla}_{k} A^{i}$ is a tensor, the covariant derivative of this will have the same indexing as a tensor $T_k^i$:\n", "\n", "$$\n", "\\hat{\\nabla}_{j} T^i_k = T^i_{k,j} + \\hat{\\Gamma}^i_{dj} T^d_k - \\hat{\\Gamma}^d_{kj} T^i_d.\n", "$$\n", "\n", "Therefore,\n", "\\begin{align}\n", "\\hat{\\nabla}_{j} \\left(\\hat{\\nabla}_{k} A^{i}\\right) &= \\left(A^i_{,k} + \\hat{\\Gamma}^i_{mk} A^m\\right)_{,j} + \\hat{\\Gamma}^i_{dj} \\left(A^d_{,k} + \\hat{\\Gamma}^d_{mk} A^m\\right) - \\hat{\\Gamma}^d_{kj} \\left(A^i_{,d} + \\hat{\\Gamma}^i_{md} A^m\\right) \\\\\n", "&= A^i_{,kj} + \\hat{\\Gamma}^i_{mk,j} A^m + \\hat{\\Gamma}^i_{mk} A^m_{,j} + \\hat{\\Gamma}^i_{dj}A^d_{,k} + \\hat{\\Gamma}^i_{dj}\\hat{\\Gamma}^d_{mk} A^m - \\hat{\\Gamma}^d_{kj} A^i_{,d} - \\hat{\\Gamma}^d_{kj} \\hat{\\Gamma}^i_{md} A^m \\\\\n", "&= {\\underbrace {\\textstyle A^i_{,kj}}_{\\text{Term 1}}} +\n", "{\\underbrace {\\textstyle \\hat{\\Gamma}^i_{mk,j} A^m + \\hat{\\Gamma}^i_{mk} A^m_{,j} + \\hat{\\Gamma}^i_{dj} A^d_{,k} - \\hat{\\Gamma}^d_{kj} A^i_{,d}}_{\\text{Term 2}}} +\n", "{\\underbrace {\\textstyle \\hat{\\Gamma}^i_{dj}\\hat{\\Gamma}^d_{mk} A^m - \\hat{\\Gamma}^d_{kj} \\hat{\\Gamma}^i_{md} A^m}_{\\text{Term 3}}},\n", "\\end{align}\n", "\n", "resulting in\n", "\n", "$$\n", "\\partial_t E^i = \\hat{g}^{ij}\\partial_j \\Gamma - \\hat{g}^{jk} \\hat{\\nabla}_{j} \\left(\\hat{\\nabla}_{k} A^{i}\\right) = \\hat{g}^{ij}\\partial_j \\Gamma - \\hat{g}^{jk} \\left(\\text{Term 1} + \\text{Term 2} + \\text{Term 3}\\right)\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "## Step 1b: System II in Curvilinear Coordinates, using the rescaled quantities $a^i$ and $e^i$ \\[Back to [top](#top)\\]\n", "$$\\label{step3b}$$\n", "\n", "Consider an arbitrary vector $\\Lambda^i$, with smooth (continous) Cartesian components $\\Lambda^x$, $\\Lambda^y$, and $\\Lambda^z$. Transforming $\\Lambda^i$ to, e.g. spherical coordinates, introduces terms that spoil the smoothness of $\\Lambda^i$;\n", "\n", "$$\n", "\\Lambda^\\phi = \\frac{1}{r \\sin \\theta} \\times \\left[ \\text{smooth part} \\right].\n", "$$\n", "\n", "Evolving $\\Lambda^\\phi$ will introduce instabilities along the $z$-axis. To avoid this, we instead evolve the _rescaled_ quantity $\\lambda^i$, defined by \n", "\n", "$$\n", "\\bar{\\Lambda}^i = \\frac{\\lambda^i}{\\text{scalefactor}[i]}.\n", "$$\n", "\n", "where we use the [Hadamard product](https://en.wikipedia.org/w/index.php?title=Hadamard_product_(matrices)&oldid=852272177) of matrices, and no sums are implied by the repeated indices.\n", "\n", "Thus, we evolve the smoothed variable $\\lambda^i$, via \n", "\n", "$$\n", "\\lambda^i = \\bar{\\Lambda}^i \\text{scalefactor}[i].\n", "$$\n", "\n", "Within Nrpy+, ReU[i] = 1/scalefactor[i], giving \n", "\n", "$$\n", "\\lambda^i = \\frac{\\bar{\\Lambda}^i}{\\text{ReU}[i]}.\n", "$$\n", "\n", "We now define the rescaled quantities $a^i$ and $e^i$ and rewrite our formulation of Maxwell's equations in curvilinear coordinates;\n", "\n", "\\begin{align}\n", "a^i &= \\frac{A^i}{\\text{ReU}[i]},\\\\ \\\\\n", "e^i &= \\frac{E^i}{\\text{ReU}[i]},\n", "\\end{align}\n", "\n", "Taking a time derivative on both sides,\n", "\n", "\\begin{align}\n", "\\partial_t a^i &= \\frac{\\partial_t A^i}{\\text{ReU}[i]} = \\frac{ -E^i - \\hat{g}^{ij}\\partial_j \\varphi}{\\text{ReU}[i]} = -e^i - \\frac{\\hat{g}^{ij}\\partial_j \\varphi}{\\text{ReU}[i]},\\\\ \\\\\n", "\\partial_t e^i &= \\frac{\\partial_t E^i}{\\text{ReU}[i]} = \\frac{\\hat{g}^{ij}\\partial_j \\Gamma - \\hat{g}^{jk} \\hat{\\nabla}_{j} \\left(\\hat{\\nabla}_{k} A^{i}\\right)}{\\text{ReU}[i]} = \\frac{\\hat{g}^{ij}\\partial_j \\Gamma}{\\text{ReU}[i]} - \\frac{\\hat{g}^{jk} \\hat{\\nabla}_{j} \\left(\\hat{\\nabla}_{k} a^{i} \\text{ReU}[i] \\right)}{\\text{ReU}[i]},\n", "\\end{align}\n", "\n", "Given that\n", "\n", "$$\n", "\\partial_t E^i = {\\underbrace {\\textstyle \\hat{g}^{ij}\\partial_j \\Gamma}_{\\text{Term 1}}} - \\hat{\\gamma}^{jk} \\left({\\underbrace {\\textstyle A^i_{,kj}}_{\\text{Term 2}}} + {\\underbrace {\\textstyle \\hat{\\Gamma}^i_{mk,j} A^m + \\hat{\\Gamma}^i_{mk} A^m_{,j} + \\hat{\\Gamma}^i_{dj} A^d_{,k} - \\hat{\\Gamma}^d_{kj} A^i_{,d}}_{\\text{Term 3}}} + {\\underbrace {\\textstyle \\hat{\\Gamma}^i_{dj}\\hat{\\Gamma}^d_{mk} A^m - \\hat{\\Gamma}^d_{kj} \\hat{\\Gamma}^i_{md} A^m}_{\\text{Term 4}}}\\right).\n", "$$\n", "\n", "we can make the following replacements within the above, in terms of NRPy+ code;\n", "\n", "\\begin{align}\n", "A^i = \\text{AU[i]} &\\to \\text{aU[i] * rfm.ReU[i]} \\\\\n", "\\partial_j A^i = \\text{AUdD[i][j]} &\\to \\text{aU_dD[i][j] * rfm.ReU[i]} +\\text{aU[i] * rfm.ReUdD[i][j]} \\\\\n", "\\partial_k \\partial_j A^i = \\text{AUdDD[i][j][k]} &\\to \n", "\\text{aU_dDD[i][j][k] * rfm.ReU[i]} + \n", "\\text{aU_dDD[i][j] * rfm.ReUdD[i][k]} \\\\\n", "&+ \\text{aU_dD[i][k] * rfm.ReUdD[i][j]} +\n", "\\text{aU[i] * rfm.ReUdDD[i][j][k]}\n", "\\end{align}\n", "\n", "\n", "The remainder of Maxwell's equations are unchanged;\n", "\n", "$$\n", "\\partial_t \\Gamma = -\\hat{g}^{ij} \\left( \\partial_i \\partial_j \\varphi - \\hat{\\Gamma}^k_{ji} \\partial_k \\varphi \\right),\n", "$$\n", "\n", "$$\n", "\\partial_t \\varphi = -\\Gamma,\n", "$$\n", "\n", "subject to constraints\n", "\n", "\\begin{align}\n", "\\mathcal{G} &\\equiv \\Gamma - \\partial_i A^i - \\hat{\\Gamma}^i_{ji} A^j &= 0,\\\\\n", "\\mathcal{C} &\\equiv \\partial_i E^i + \\hat{\\Gamma}^i_{ji} E^j &= 0.\n", "\\end{align}\n", "\n", "These equations are implemement in [this tutorial](Tutorial-VacuumMaxwell_Curvilinear_RHSs.ipynb), and evolved in time in [this tutorial](Tutorial-Start_to_Finish-Solving_Maxwells_Equations_in_Vacuum-Curvilinear.ipynb)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Step 2: 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_Curvilinear.pdf](Tutorial-VacuumMaxwell_formulation_Curvilinear.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:07.890993Z", "iopub.status.busy": "2021-03-07T17:19:07.890013Z", "iopub.status.idle": "2021-03-07T17:19:10.954805Z", "shell.execute_reply": "2021-03-07T17:19:10.955810Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created Tutorial-VacuumMaxwell_formulation_Curvilinear.tex, and compiled\n", " LaTeX file to PDF file Tutorial-\n", " VacuumMaxwell_formulation_Curvilinear.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_Curvilinear\")" ] } ], "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 }