{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "# Converting *Exact* ADM Initial Data in the Spherical or Cartesian Basis to BSSN Initial Data in the Desired Curvilinear Basis\n", "## Author: Zach Etienne\n", "### Formatting improvements courtesy Brandon Clark\n", "\n", "[comment]: <> (Abstract: TODO)\n", "\n", "### This module is meant for use only with initial data that can be represented exactly in ADM form, either in the Spherical or Cartesian basis. I.e., the ADM variables are given $\\left\\{\\gamma_{ij}, K_{ij}, \\alpha, \\beta^i\\right\\}$ *exactly* as functions of $(r,\\theta,\\phi)$ or $(x,y,z)$, respectively. If instead the initial data are given only numerically (e.g., through an initial data solver), then [the Numerical-ADM-Spherical/Cartesian-to-BSSNCurvilinear module](Tutorial-ADM_Initial_Data-Converting_Numerical_ADM_Spherical_or_Cartesian_to_BSSNCurvilinear.ipynb) will need to be used instead. \n", "\n", "**Notebook Status:** Self-Validated \n", "\n", "**Validation Notes:** This tutorial notebook has been confirmed to be self-consistent with its corresponding NRPy+ module, as documented [below](#code_validation). **Additional validation tests may have been performed, but are as yet, undocumented. (TODO)**\n", "\n", "### NRPy+ Source Code for this module: [BSSN/ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear.py](../edit/BSSN/ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear.py)\n", "\n", "\n", "\n", "## Introduction:\n", "Given the ADM variables:\n", "\n", "$$\\left\\{\\gamma_{ij}, K_{ij}, \\alpha, \\beta^i\\right\\}$$\n", "\n", "in the Spherical or Cartesian basis, and as functions of $(r,\\theta,\\phi)$ or $(x,y,z)$, respectively, this module documents their conversion to the BSSN variables\n", "\n", "$$\\left\\{\\bar{\\gamma}_{i j},\\bar{A}_{i j},\\phi, K, \\bar{\\Lambda}^{i}, \\alpha, \\beta^i, B^i\\right\\},$$ \n", "\n", "in the desired curvilinear basis (given by `reference_metric::CoordSystem`). Then it rescales the resulting BSSNCurvilinear variables (as defined in [the covariant BSSN formulation tutorial](Tutorial-BSSN_formulation.ipynb)) into the form needed for solving Einstein's equations with the BSSN formulation:\n", "\n", "$$\\left\\{h_{i j},a_{i j},\\phi, K, \\lambda^{i}, \\alpha, \\mathcal{V}^i, \\mathcal{B}^i\\right\\}.$$ \n", "\n", "We will use as our core example in this module UIUC initial data, which are ([as documented in their NRPy+ initial data module](Tutorial-ADM_Initial_Data-UIUC_BlackHole.ipynb)) given in terms of ADM variables in Spherical coordinates." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Table of Contents\n", "$$\\label{toc}$$ \n", "\n", "This notebook is organized as follows\n", "\n", "1. [Step 1](#initializenrpy): Initialize core Python/NRPy+ modules\n", "1. [Step 2](#cylindrical): Desired output BSSN Curvilinear coordinate system set to Cylindrical, as a proof-of-principle\n", "1. [Step 3](#admxx0xx1xx2): Converting ADM variables to functions of (`xx0,xx1,xx2`)\n", "1. [Step 4](#adm_jacobian): Applying Jacobian transformations to get in the correct `xx0,xx1,xx2` basis\n", "1. [Step 5](#adm2bssn): Call functions within [`BSSN.BSSN_in_terms_of_ADM`](../edit/BSSN/BSSN_in_terms_of_ADM.py) ([**tutorial**](Tutorial-BSSN_in_terms_of_ADM.ipynb)) to perform the ADM-to-BSSN conversion\n", "1. [Step 6](#code_validation): Code Validation against `BSSN.ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear` NRPy+ module\n", "1. [Step 7](#latex_pdf_output): Output this notebook to $\\LaTeX$-formatted PDF file" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Step 1: Initialize core Python/NRPy+ modules \\[Back to [top](#toc)\\]\n", "$$\\label{initializenrpy}$$" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:05:30.774707Z", "iopub.status.busy": "2021-03-07T17:05:30.773993Z", "iopub.status.idle": "2021-03-07T17:05:31.104423Z", "shell.execute_reply": "2021-03-07T17:05:31.105002Z" } }, "outputs": [], "source": [ "# Step P1: Import needed NRPy+ core modules:\n", "import sympy as sp # SymPy: The Python computer algebra package upon which NRPy+ depends\n", "import indexedexp as ixp # NRPy+: Symbolic indexed expression (e.g., tensors, vectors, etc.) support\n", "import reference_metric as rfm # NRPy+: Reference metric support\n", "import NRPy_param_funcs as par # NRPy+: Parameter interface\n", "import sys # Standard Python module for multiplatform OS-level functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Step 2: Desired output BSSN Curvilinear coordinate system set to Cylindrical, as a proof-of-principle \\[Back to [top](#toc)\\]\n", "$$\\label{cylindrical}$$" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:05:31.114955Z", "iopub.status.busy": "2021-03-07T17:05:31.114323Z", "iopub.status.idle": "2021-03-07T17:05:31.464032Z", "shell.execute_reply": "2021-03-07T17:05:31.463501Z" } }, "outputs": [], "source": [ "# The ADM & BSSN formalisms only work in 3D; they are 3+1 decompositions of Einstein's equations.\n", "# To implement axisymmetry or spherical symmetry, simply set all spatial derivatives in\n", "# the relevant angular directions to zero; DO NOT SET DIM TO ANYTHING BUT 3.\n", "\n", "# Step P1: Set spatial dimension (must be 3 for BSSN)\n", "DIM = 3\n", "\n", "# Set the desired *output* coordinate system to Cylindrical:\n", "par.set_parval_from_str(\"reference_metric::CoordSystem\",\"Cylindrical\")\n", "rfm.reference_metric()\n", "\n", "# Import UIUC Black Hole initial data\n", "import BSSN.UIUCBlackHole as uibh\n", "uibh.UIUCBlackHole(ComputeADMGlobalsOnly=True)\n", "Sph_r_th_ph_or_Cart_xyz = [uibh.r,uibh.th,uibh.ph]\n", "alphaSphorCart = uibh.alphaSph\n", "betaSphorCartU = uibh.betaSphU\n", "BSphorCartU = uibh.BSphU\n", "gammaSphorCartDD = uibh.gammaSphDD\n", "KSphorCartDD = uibh.KSphDD" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Step 3: Converting ADM variables to functions of ${\\rm xx0},{\\rm xx1},{\\rm xx2}$ \\[Back to [top](#toc)\\]\n", "$$\\label{admxx0xx1xx2}$$\n", "\n", "ADM variables are given as functions of $(r,\\theta,\\phi)$ or $(x,y,z)$. We convert them to functions of `(xx0,xx1,xx2)` using SymPy's `subs()` function." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:05:31.508150Z", "iopub.status.busy": "2021-03-07T17:05:31.472280Z", "iopub.status.idle": "2021-03-07T17:05:31.556430Z", "shell.execute_reply": "2021-03-07T17:05:31.557033Z" } }, "outputs": [], "source": [ "# Step 3: All input quantities are in terms of r,th,ph or x,y,z. We want them in terms\n", "# of xx0,xx1,xx2, so here we call sympify_integers__replace_rthph() to replace\n", "# r,th,ph or x,y,z, respectively, with the appropriate functions of xx0,xx1,xx2\n", "# as defined for this particular reference metric in reference_metric.py's\n", "# xxSph[] or xx_to_Cart[], respectively:\n", "\n", "# UIUC Black Hole initial data are given in Spherical coordinates.\n", "CoordType_in = \"Spherical\"\n", "\n", "# Make sure that rfm.reference_metric() has been called.\n", "# We'll need the variables it defines throughout this module.\n", "if rfm.have_already_called_reference_metric_function == False:\n", " print(\"Error. Called Convert_Spherical_ADM_to_BSSN_curvilinear() without\")\n", " print(\" first setting up reference metric, by calling rfm.reference_metric().\")\n", " sys.exit(1)\n", "\n", "# Note that substitution only works when the variable is not an integer. Hence the\n", "# if isinstance(...,...) stuff:\n", "def sympify_integers__replace_rthph_or_Cartxyz(obj, rthph_or_xyz, rthph_or_xyz_of_xx):\n", " if isinstance(obj, int):\n", " return sp.sympify(obj)\n", " else:\n", " return obj.subs(rthph_or_xyz[0], rthph_or_xyz_of_xx[0]).\\\n", " subs(rthph_or_xyz[1], rthph_or_xyz_of_xx[1]).\\\n", " subs(rthph_or_xyz[2], rthph_or_xyz_of_xx[2])\n", "\n", "r_th_ph_or_Cart_xyz_of_xx = []\n", "if CoordType_in == \"Spherical\":\n", " r_th_ph_or_Cart_xyz_of_xx = rfm.xxSph\n", "elif CoordType_in == \"Cartesian\":\n", " r_th_ph_or_Cart_xyz_of_xx = rfm.xx_to_Cart\n", "else:\n", " print(\"Error: Can only convert ADM Cartesian or Spherical initial data to BSSN Curvilinear coords.\")\n", " sys.exit(1)\n", "\n", "alphaSphorCart = sympify_integers__replace_rthph_or_Cartxyz(\n", " alphaSphorCart, Sph_r_th_ph_or_Cart_xyz, r_th_ph_or_Cart_xyz_of_xx)\n", "for i in range(DIM):\n", " betaSphorCartU[i] = sympify_integers__replace_rthph_or_Cartxyz(\n", " betaSphorCartU[i], Sph_r_th_ph_or_Cart_xyz, r_th_ph_or_Cart_xyz_of_xx)\n", " BSphorCartU[i] = sympify_integers__replace_rthph_or_Cartxyz(\n", " BSphorCartU[i], Sph_r_th_ph_or_Cart_xyz, r_th_ph_or_Cart_xyz_of_xx)\n", " for j in range(DIM):\n", " gammaSphorCartDD[i][j] = sympify_integers__replace_rthph_or_Cartxyz(\n", " gammaSphorCartDD[i][j], Sph_r_th_ph_or_Cart_xyz, r_th_ph_or_Cart_xyz_of_xx)\n", " KSphorCartDD[i][j] = sympify_integers__replace_rthph_or_Cartxyz(\n", " KSphorCartDD[i][j], Sph_r_th_ph_or_Cart_xyz, r_th_ph_or_Cart_xyz_of_xx)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Step 4: Applying Jacobian transformations to get in the correct `xx0,xx1,xx2` basis \\[Back to [top](#toc)\\]\n", "$$\\label{adm_jacobian}$$\n", "\n", "All ADM initial data quantities are now functions of `xx0,xx1,xx2`, but they are still in the Spherical or Cartesian basis. We can now directly apply Jacobian transformations to get them in the correct `xx0,xx1,xx2` basis. The following discussion holds for either Spherical or Cartesian input data, so for simplicity let's just assume the data are given in Spherical coordinates.\n", "\n", "All ADM tensors and vectors are in the Spherical coordinate basis $x^i_{\\rm Sph} = (r,\\theta,\\phi)$, but we need them in the curvilinear coordinate basis $x^i_{\\rm rfm}=$`(xx0,xx1,xx2)` set by the `\"reference_metric::CoordSystem\"` variable. Empirically speaking, it is far easier to write `(x(xx0,xx1,xx2),y(xx0,xx1, xx2),z(xx0,xx1,xx2))` than the inverse, so we will compute the Jacobian matrix\n", "\n", "$$\n", "{\\rm Jac\\_dUSph\\_dDrfmUD[i][j]} = \\frac{\\partial x^i_{\\rm Sph}}{\\partial x^j_{\\rm rfm}},\n", "$$\n", "\n", "via exact differentiation (courtesy SymPy), and the inverse Jacobian\n", "$$\n", "{\\rm Jac\\_dUrfm\\_dDSphUD[i][j]} = \\frac{\\partial x^i_{\\rm rfm}}{\\partial x^j_{\\rm Sph}},\n", "$$\n", "\n", "using NRPy+'s `generic_matrix_inverter3x3()` function. In terms of these, the transformation of BSSN tensors from Spherical to `\"reference_metric::CoordSystem\"` coordinates may be written:\n", "\n", "\\begin{align}\n", "\\beta^i_{\\rm rfm} &= \\frac{\\partial x^i_{\\rm rfm}}{\\partial x^\\ell_{\\rm Sph}} \\beta^\\ell_{\\rm Sph}\\\\\n", "B^i_{\\rm rfm} &= \\frac{\\partial x^i_{\\rm rfm}}{\\partial x^\\ell_{\\rm Sph}} B^\\ell_{\\rm Sph}\\\\\n", "\\gamma^{\\rm rfm}_{ij} &= \n", "\\frac{\\partial x^\\ell_{\\rm Sph}}{\\partial x^i_{\\rm rfm}}\n", "\\frac{\\partial x^m_{\\rm Sph}}{\\partial x^j_{\\rm rfm}} \\gamma^{\\rm Sph}_{\\ell m}\\\\\n", "K^{\\rm rfm}_{ij} &= \n", "\\frac{\\partial x^\\ell_{\\rm Sph}}{\\partial x^i_{\\rm rfm}}\n", "\\frac{\\partial x^m_{\\rm Sph}}{\\partial x^j_{\\rm rfm}} K^{\\rm Sph}_{\\ell m}\n", "\\end{align}" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:05:31.610714Z", "iopub.status.busy": "2021-03-07T17:05:31.595558Z", "iopub.status.idle": "2021-03-07T17:05:31.613158Z", "shell.execute_reply": "2021-03-07T17:05:31.613676Z" } }, "outputs": [], "source": [ "# Step 2: All ADM initial data quantities are now functions of xx0,xx1,xx2, but\n", "# they are still in the Spherical or Cartesian basis. We can now directly apply\n", "# Jacobian transformations to get them in the correct xx0,xx1,xx2 basis:\n", "\n", "# alpha is a scalar, so no Jacobian transformation is necessary.\n", "alpha = alphaSphorCart\n", "\n", "Jac_dUSphorCart_dDrfmUD = ixp.zerorank2()\n", "for i in range(DIM):\n", " for j in range(DIM):\n", " Jac_dUSphorCart_dDrfmUD[i][j] = sp.simplify(sp.diff(r_th_ph_or_Cart_xyz_of_xx[i],rfm.xx[j]))\n", "\n", "Jac_dUrfm_dDSphorCartUD, dummyDET = ixp.generic_matrix_inverter3x3(Jac_dUSphorCart_dDrfmUD)\n", "\n", "betaU = ixp.zerorank1()\n", "BU = ixp.zerorank1()\n", "gammaDD = ixp.zerorank2()\n", "KDD = ixp.zerorank2()\n", "for i in range(DIM):\n", " for j in range(DIM):\n", " betaU[i] += Jac_dUrfm_dDSphorCartUD[i][j] * betaSphorCartU[j]\n", " BU[i] += Jac_dUrfm_dDSphorCartUD[i][j] * BSphorCartU[j]\n", " for k in range(DIM):\n", " for l in range(DIM):\n", " gammaDD[i][j] += Jac_dUSphorCart_dDrfmUD[k][i]*Jac_dUSphorCart_dDrfmUD[l][j] * gammaSphorCartDD[k][l]\n", " KDD[i][j] += Jac_dUSphorCart_dDrfmUD[k][i]*Jac_dUSphorCart_dDrfmUD[l][j] * KSphorCartDD[k][l]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Step 5: Call functions within [`BSSN.BSSN_in_terms_of_ADM`](../edit/BSSN/BSSN_in_terms_of_ADM.py) ([**tutorial**](Tutorial-BSSN_in_terms_of_ADM.ipynb)) to perform the ADM-to-BSSN conversion \\[Back to [top](#toc)\\]\n", "$$\\label{adm2bssn}$$\n", "\n", "All ADM quantities were input into this function in the Spherical or Cartesian basis, as functions of $r,\\theta,\\phi$ or $x,y,z$, respectively. In [Step 3](#admxx0xx1xx2) and [Step 4](#adm_jacobian) above, we converted them to the `xx0,xx1,xx2` basis, and as functions of `xx0,xx1,xx2`. Here we convert ADM 3-metric, extrinsic curvature, and gauge quantities in the `xx0,xx1,xx2` (a.k.a. \"rfm\") basis to their BSSN Curvilinear counterparts, in the same basis." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:05:31.619724Z", "iopub.status.busy": "2021-03-07T17:05:31.618959Z", "iopub.status.idle": "2021-03-07T17:05:46.744530Z", "shell.execute_reply": "2021-03-07T17:05:46.744041Z" } }, "outputs": [], "source": [ "import BSSN.BSSN_in_terms_of_ADM as BitoA\n", "BitoA.gammabarDD_hDD( gammaDD)\n", "BitoA.trK_AbarDD_aDD( gammaDD,KDD)\n", "BitoA.LambdabarU_lambdaU__exact_gammaDD(gammaDD)\n", "BitoA.cf_from_gammaDD( gammaDD)\n", "BitoA.betU_vetU( betaU,BU)\n", "hDD = BitoA.hDD\n", "trK = BitoA.trK\n", "aDD = BitoA.aDD\n", "lambdaU = BitoA.lambdaU\n", "cf = BitoA.cf\n", "vetU = BitoA.vetU\n", "betU = BitoA.betU" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Step 6: Code Validation against `BSSN.ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear` 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.ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear](../edit/BSSN/ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear.py) module.\n", "\n", "By default, we analyze these expressions in Spherical coordinates, though other coordinate systems may be chosen." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:05:46.790410Z", "iopub.status.busy": "2021-03-07T17:05:46.754339Z", "iopub.status.idle": "2021-03-07T17:05:55.637646Z", "shell.execute_reply": "2021-03-07T17:05:55.638145Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Consistency check between this tutorial notebook and BSSN.ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear NRPy+ module: ALL SHOULD BE ZERO.\n", "cf - mod_cf = 0\n", "trK - mod_trK = 0\n", "alpha - mod_alpha = 0\n", "vetU[0] - mod_vetU[0] = 0\n", "betU[0] - mod_betU[0] = 0\n", "lambdaU[0] - mod_lambdaU[0] = 0\n", "hDD[0][0] - mod_hDD[0][0] = 0\n", "aDD[0][0] - mod_aDD[0][0] = 0\n", "hDD[0][1] - mod_hDD[0][1] = 0\n", "aDD[0][1] - mod_aDD[0][1] = 0\n", "hDD[0][2] - mod_hDD[0][2] = 0\n", "aDD[0][2] - mod_aDD[0][2] = 0\n", "vetU[1] - mod_vetU[1] = 0\n", "betU[1] - mod_betU[1] = 0\n", "lambdaU[1] - mod_lambdaU[1] = 0\n", "hDD[1][0] - mod_hDD[1][0] = 0\n", "aDD[1][0] - mod_aDD[1][0] = 0\n", "hDD[1][1] - mod_hDD[1][1] = 0\n", "aDD[1][1] - mod_aDD[1][1] = 0\n", "hDD[1][2] - mod_hDD[1][2] = 0\n", "aDD[1][2] - mod_aDD[1][2] = 0\n", "vetU[2] - mod_vetU[2] = 0\n", "betU[2] - mod_betU[2] = 0\n", "lambdaU[2] - mod_lambdaU[2] = 0\n", "hDD[2][0] - mod_hDD[2][0] = 0\n", "aDD[2][0] - mod_aDD[2][0] = 0\n", "hDD[2][1] - mod_hDD[2][1] = 0\n", "aDD[2][1] - mod_aDD[2][1] = 0\n", "hDD[2][2] - mod_hDD[2][2] = 0\n", "aDD[2][2] - mod_aDD[2][2] = 0\n" ] } ], "source": [ "import BSSN.UIUCBlackHole as uibh\n", "import BSSN.ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear as ADMtoBSSN\n", "uibh.UIUCBlackHole()\n", "mod_cf,mod_hDD,mod_lambdaU,mod_aDD,mod_trK,mod_alpha,mod_vetU,mod_betU = \\\n", " ADMtoBSSN.Convert_Spherical_or_Cartesian_ADM_to_BSSN_curvilinear(\"Spherical\",uibh.Sph_r_th_ph,\n", " uibh.gammaSphDD, uibh.KSphDD, uibh.alphaSph, uibh.betaSphU, uibh.BSphU)\n", "\n", "print(\"Consistency check between this tutorial notebook and BSSN.ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear NRPy+ module: ALL SHOULD BE ZERO.\")\n", "\n", "print(\"cf - mod_cf = \" + str(cf - mod_cf))\n", "print(\"trK - mod_trK = \" + str(trK - mod_trK))\n", "print(\"alpha - mod_alpha = \" + str(alpha - mod_alpha))\n", "\n", "for i in range(DIM):\n", " print(\"vetU[\"+str(i)+\"] - mod_vetU[\"+str(i)+\"] = \" + str(vetU[i] - mod_vetU[i]))\n", " print(\"betU[\"+str(i)+\"] - mod_betU[\"+str(i)+\"] = \" + str(betU[i] - mod_betU[i]))\n", " print(\"lambdaU[\"+str(i)+\"] - mod_lambdaU[\"+str(i)+\"] = \" + str(lambdaU[i] - mod_lambdaU[i]))\n", " for j in range(DIM):\n", " print(\"hDD[\"+str(i)+\"][\"+str(j)+\"] - mod_hDD[\"+str(i)+\"][\"+str(j)+\"] = \"\n", " + str(hDD[i][j] - mod_hDD[i][j]))\n", " print(\"aDD[\"+str(i)+\"][\"+str(j)+\"] - mod_aDD[\"+str(i)+\"][\"+str(j)+\"] = \"\n", " + str(aDD[i][j] - mod_aDD[i][j]))\n", "\n", "# If you wish to generate & analyze C code output, uncomment the following:\n", "# import os, shutil # Standard Python modules for multiplatform OS-level functions\n", "# import cmdline_helper as cmd # NRPy+: Multi-platform Python command-line interface\n", "# # Step P2: Create C code output directory:\n", "# Ccodesdir = os.path.join(\"BSSN_Exact_ADM_validation/\")\n", "# # First remove C code output directory if it exists\n", "# # Courtesy https://stackoverflow.com/questions/303200/how-do-i-remove-delete-a-folder-that-is-not-empty\n", "# # !rm -r ScalarWaveCurvilinear_Playground_Ccodes\n", "# shutil.rmtree(Ccodesdir, ignore_errors=True)\n", "# # Then create a fresh directory\n", "# cmd.mkdir(Ccodesdir)\n", "# with open(os.path.join(Ccodedir,\"UIUCBlackHole-CylindricalTest.h\"),\"w\") as file:\n", "# file.write(uibh.returnfunction)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# Step 7: 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-ADM_Initial_Data-Converting_Exact_ADM_Spherical_or_Cartesian_to_BSSNCurvilinear.pdf](Tutorial-ADM_Initial_Data-Converting_Exact_ADM_Spherical_or_Cartesian_to_BSSNCurvilinear.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": 7, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:05:55.642789Z", "iopub.status.busy": "2021-03-07T17:05:55.642096Z", "iopub.status.idle": "2021-03-07T17:05:59.130847Z", "shell.execute_reply": "2021-03-07T17:05:59.131953Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created Tutorial-ADM_Initial_Data-\n", " Converting_Exact_ADM_Spherical_or_Cartesian_to_BSSNCurvilinear.tex, and\n", " compiled LaTeX file to PDF file Tutorial-ADM_Initial_Data-\n", " Converting_Exact_ADM_Spherical_or_Cartesian_to_BSSNCurvilinear.pdf\n" ] } ], "source": [ "import cmdline_helper as cmd # NRPy+: Multi-platform Python command-line interface\n", "cmd.output_Jupyter_notebook_to_LaTeXed_PDF(\"Tutorial-ADM_Initial_Data-Converting_Exact_ADM_Spherical_or_Cartesian_to_BSSNCurvilinear\")" ] } ], "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.0" } }, "nbformat": 4, "nbformat_minor": 2 }