{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"\n",
"# Start-to-Finish Example: Evolving Maxwell's Equations with Toriodal Dipole Field Initial Data, in Flat Spacetime and Curvilinear Coordinates\n",
"\n",
"## Following the work of [Knapp, Walker & Baumgarte (2002)](https://arxiv.org/abs/gr-qc/0201051), we numerically implement the second version of Maxwell’s equations - System II (BSSN - like) in curvilinear coordinates.\n",
"\n",
"## Author: Terrence Pierre Jacques and Zachariah Etienne\n",
"### Formatting improvements courtesy Brandon Clark\n",
"\n",
"**Notebook Status:** Validated \n",
"\n",
"**Validation Notes:** This module has been validated to exhibit convergence to the exact solution for the electric field $E^i$ and vector potential $A^i$ at the expected order, *after a short numerical evolution of the initial data* (see [plots at bottom](#convergence)).\n",
"\n",
"### NRPy+ Source Code for this module: \n",
"* [Maxwell/InitialData.py](../edit/Maxwell/InitialData.py); [\\[**tutorial**\\]](Tutorial-VacuumMaxwell_InitialData.ipynb): Purely toriodal dipole field initial data; sets all electromagnetic variables in the Cartesian basis\n",
"* [Maxwell/VacuumMaxwell_Flat_Evol_Curvilinear.py](../edit/Maxwell/VacuumMaxwell_Flat_Evol_Cartesian.py); [\\[**tutorial**\\]](Tutorial-Tutorial-VacuumMaxwell_Curvilinear_RHS-Rescaling.ipynb): Generates the right-hand sides for Maxwell's equations in curvilinear coordinates\n",
"\n",
"## Introduction:\n",
"Here we use NRPy+ to generate the C source code necessary to set up initial data for a purely toriodal dipole field, as defined in [Knapp, Walker & Baumgarte (2002)](https://arxiv.org/abs/gr-qc/0201051). We then evolve the RHSs of Maxwell's equations using the [Method of Lines](https://reference.wolfram.com/language/tutorial/NDSolveMethodOfLines.html) time integration based on an [explicit Runge-Kutta fourth-order scheme](https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods) (RK4 is chosen below, but multiple options exist). \n",
"\n",
"The entire algorithm is outlined as follows, with links to the relevant NRPy+ tutorial notebooks listed at each step:\n",
"\n",
"1. Allocate memory for gridfunctions, including temporary storage for the Method of Lines time integration\n",
" * [**NRPy+ tutorial on Method of Lines algorithm**](Tutorial-Method_of_Lines-C_Code_Generation.ipynb).\n",
"1. Set gridfunction values to initial data \n",
" * [**NRPy+ tutorial on purely toriodal dipole field initial data**](Tutorial-VacuumMaxwell_InitialData.ipynb)\n",
"1. Next, integrate the initial data forward in time using the Method of Lines coupled to a Runge-Kutta explicit timestepping algorithm:\n",
" 1. At the start of each iteration in time, output the divergence constraint violation \n",
" * [**NRPy+ tutorial on Maxwell's equations constraints**](Tutorial-VacuumMaxwell_Curvilinear_RHSs.ipynb)\n",
" 1. At each RK time substep, do the following:\n",
" 1. Evaluate RHS expressions \n",
" * [**NRPy+ tutorial on Maxwell's equations right-hand sides**](Tutorial-VacuumMaxwell_Curvilinear_RHSs.ipynb)\n",
" 1. Apply Sommerfeld boundary conditions in curvilinear coordinates\n",
" * [**NRPy+ tutorial on setting up Sommerfeld boundary conditions**](Tutorial-SommerfeldBoundaryCondition.ipynb) \n",
"1. Repeat above steps at two numerical resolutions to confirm convergence to zero."
]
},
{
"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): Set core NRPy+ parameters for numerical grids and reference metric\n",
" 1. [Step 1.a](#cfl) Output needed C code for finding the minimum proper distance between grid points, needed for [CFL](https://en.wikipedia.org/w/index.php?title=Courant%E2%80%93Friedrichs%E2%80%93Lewy_condition&oldid=806430673)-limited timestep\n",
"1. [Step 2](#mw): Generate symbolic expressions and output C code for evolving Maxwell's equations\n",
" 1. [Step 2.a](#mwid): Generate symbolic expressions for toroidal dipole field initial data\n",
" 1. [Step 2.b](#mwevol): Generate symbolic expressions for evolution equations\n",
" 1. [Step 2.c](#mwcon): Generate symbolic expressions for constraint equations\n",
" 1. [Step 2.d](#mwcart): Generate symbolic expressions for converting $A^i$ and $E^i$ to the Cartesian basis\n",
" 1. [Step 2.e](#mwccode): Output C codes for initial data and evolution equations\n",
" 1. [Step 2.f](#mwccode_con): Output C code for constraint equations\n",
" 1. [Step 2.g](#mwccode_cart): Output C code for converting $A^i$ and $E^i$ to Cartesian coordinates\n",
" 1. [Step 2.h](#mwccode_xzloop): Output C code for printing 2D data\n",
" 1. [Step 2.i](#cparams_rfm_and_domainsize): Output C codes needed for declaring and setting Cparameters; also set `free_parameters.h`\n",
"1. [Step 3](#bc_functs): Set up Sommerfeld boundary condition functions\n",
"1. [Step 4](#mainc): `Maxwell_Playground.c`: The Main C Code\n",
"1. [Step 5](#compileexec): Compile generated C codes & perform simulation of the propagating toriodal electromagnetic field\n",
"1. [Step 6](#visualize): Visualize the output!\n",
" 1. [Step 6.a](#installdownload): Install `scipy` and download `ffmpeg` if they are not yet installed/downloaded\n",
" 1. [Step 6.b](#genimages): Generate images for visualization animation\n",
" 1. [Step 6.c](#genvideo): Generate visualization animation\n",
"1. [Step 7](#convergence): Plot the numerical error, and confirm that it converges to zero with increasing numerical resolution (sampling)\n",
"1. [Step 8](#div_e): Comparison of Divergence Constrain Violation\n",
"1. [Step 9](#latex_pdf_output): Output this notebook to $\\LaTeX$-formatted PDF file"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"# Step 1: Set core NRPy+ parameters for numerical grids and reference metric \\[Back to [top](#toc)\\]\n",
"$$\\label{initializenrpy}$$"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:43.914614Z",
"iopub.status.busy": "2021-06-15T11:39:43.908648Z",
"iopub.status.idle": "2021-06-15T11:39:44.810620Z",
"shell.execute_reply": "2021-06-15T11:39:44.811064Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'MaxwellEvolCurvi_Playground_Ccodes/SIMD/SIMD_intrinsics.h'"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Step P1: Import needed NRPy+ core modules:\n",
"from outputC import outputC,lhrh,outCfunction # NRPy+: Core C code output module\n",
"import finite_difference as fin # NRPy+: Finite difference C code generation module\n",
"import NRPy_param_funcs as par # NRPy+: Parameter interface\n",
"import grid as gri # NRPy+: Functions having to do with numerical grids\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 cmdline_helper as cmd # NRPy+: Multi-platform Python command-line interface\n",
"import shutil, os, sys # Standard Python modules for multiplatform OS-level functions, benchmarking\n",
"\n",
"# Step P2: Create C code output directory:\n",
"Ccodesdir = os.path.join(\"MaxwellEvolCurvi_Playground_Ccodes/\")\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",
"shutil.rmtree(Ccodesdir, ignore_errors=True)\n",
"# Then create a fresh directory\n",
"cmd.mkdir(Ccodesdir)\n",
"\n",
"# Step P3: Create executable output directory:\n",
"outdir = os.path.join(Ccodesdir,\"output/\")\n",
"cmd.mkdir(outdir)\n",
"\n",
"# Step 1: Set the spatial dimension parameter\n",
"# to three (BSSN is a 3+1 decomposition\n",
"# of Einstein's equations), and then read\n",
"# the parameter as DIM.\n",
"par.set_parval_from_str(\"grid::DIM\",3)\n",
"DIM = par.parval_from_str(\"grid::DIM\")\n",
"\n",
"# Step 2: Set some core parameters, including CoordSystem MoL BoundaryCondition timestepping algorithm,\n",
"# FD order, floating point precision, and CFL factor:\n",
"# Choices are: Spherical, SinhSpherical, SinhSphericalv2, Cylindrical, SinhCylindrical,\n",
"# SymTP, SinhSymTP\n",
"CoordSystem = \"SinhCylindrical\"\n",
"\n",
"# Step 2.a: Set boundary conditions\n",
"# Current choices are QuadraticExtrapolation (quadratic polynomial extrapolation) or Sommerfeld\n",
"BoundaryCondition = \"Sommerfeld\"\n",
"\n",
"# Step 2.b: Set defaults for Coordinate system parameters.\n",
"# These are perhaps the most commonly adjusted parameters,\n",
"# so we enable modifications at this high level.\n",
"\n",
"# domain_size sets the default value for:\n",
"# * Spherical's params.RMAX\n",
"# * SinhSpherical*'s params.AMAX\n",
"# * Cartesians*'s -params.{x,y,z}min & .{x,y,z}max\n",
"# * Cylindrical's -params.ZMIN & .{Z,RHO}MAX\n",
"# * SinhCylindrical's params.AMPL{RHO,Z}\n",
"# * *SymTP's params.AMAX\n",
"domain_size = 10.0 # Needed for all coordinate systems.\n",
"\n",
"# sinh_width sets the default value for:\n",
"# * SinhSpherical's params.SINHW\n",
"# * SinhCylindrical's params.SINHW{RHO,Z}\n",
"# * SinhSymTP's params.SINHWAA\n",
"sinh_width = 0.4 # If Sinh* coordinates chosen\n",
"\n",
"# sinhv2_const_dr sets the default value for:\n",
"# * SinhSphericalv2's params.const_dr\n",
"# * SinhCylindricalv2's params.const_d{rho,z}\n",
"sinhv2_const_dr = 0.05 # If Sinh*v2 coordinates chosen\n",
"\n",
"# SymTP_bScale sets the default value for:\n",
"# * SinhSymTP's params.bScale\n",
"SymTP_bScale = 0.5 # If SymTP chosen\n",
"\n",
"# Step 2.c: Set the order of spatial and temporal derivatives;\n",
"# the core data type, and the CFL factor.\n",
"# RK_method choices include: Euler, \"RK2 Heun\", \"RK2 MP\", \"RK2 Ralston\", RK3, \"RK3 Heun\", \"RK3 Ralston\",\n",
"# SSPRK3, RK4, DP5, DP5alt, CK5, DP6, L6, DP8\n",
"RK_method = \"RK4\"\n",
"FD_order = 4 # Finite difference order: even numbers only, starting with 2. 12 is generally unstable\n",
"REAL = \"double\" # Best to use double here.\n",
"default_CFL_FACTOR= 0.5 # (GETS OVERWRITTEN WHEN EXECUTED.) In pure axisymmetry (symmetry_axes = 2 below) 1.0 works fine. Otherwise 0.5 or lower.\n",
"\n",
"# Step 3: Generate Runge-Kutta-based (RK-based) timestepping code.\n",
"# 3.A: Evaluate RHSs (RHS_string)\n",
"# 3.B: Apply boundary conditions (RHS_string)\n",
"import MoLtimestepping.C_Code_Generation as MoL\n",
"from MoLtimestepping.RK_Butcher_Table_Dictionary import Butcher_dict\n",
"RK_order = Butcher_dict[RK_method][1]\n",
"cmd.mkdir(os.path.join(Ccodesdir,\"MoLtimestepping/\"))\n",
"\n",
"RHS_string = \"rhs_eval(&rfmstruct, ¶ms, RK_INPUT_GFS, RK_OUTPUT_GFS);\"\n",
"\n",
"if BoundaryCondition == \"QuadraticExtrapolation\":\n",
" # Extrapolation BCs are applied to the evolved gridfunctions themselves after the MoL update\n",
" post_RHS_string = \"apply_bcs_curvilinear(¶ms, &bcstruct, NUM_EVOL_GFS, evol_gf_parity, RK_OUTPUT_GFS);\"\n",
"elif BoundaryCondition == \"Sommerfeld\":\n",
" # Sommerfeld BCs are applied to the gridfunction RHSs directly\n",
" RHS_string += \"\\n apply_bcs_sommerfeld(¶ms, xx, &bcstruct, NUM_EVOL_GFS, evol_gf_parity, RK_INPUT_GFS, RK_OUTPUT_GFS);\"\n",
" post_RHS_string = \"\"\n",
"else:\n",
" print(\"Invalid choice of boundary condition\")\n",
" sys.exit(1)\n",
"\n",
"MoL.MoL_C_Code_Generation(RK_method, RHS_string = RHS_string, post_RHS_string = post_RHS_string,\n",
" outdir = os.path.join(Ccodesdir,\"MoLtimestepping/\"))\n",
"\n",
"\n",
"# Step 4: Set the coordinate system for the numerical grid\n",
"par.set_parval_from_str(\"reference_metric::CoordSystem\",CoordSystem)\n",
"rfm.reference_metric()\n",
"\n",
"# Step 5: Set the finite differencing order to 4.\n",
"par.set_parval_from_str(\"finite_difference::FD_CENTDERIVS_ORDER\",FD_order)\n",
"\n",
"# Step 6: Copy SIMD/SIMD_intrinsics.h to $Ccodesdir/SIMD/SIMD_intrinsics.h\n",
"cmd.mkdir(os.path.join(Ccodesdir,\"SIMD\"))\n",
"shutil.copy(os.path.join(\"SIMD/\")+\"SIMD_intrinsics.h\",os.path.join(Ccodesdir,\"SIMD/\"))\n",
"# par.set_parval_from_str(\"indexedexp::symmetry_axes\",\"2\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 1.a: Output needed C code for finding the minimum proper distance between grid points, needed for [CFL](https://en.wikipedia.org/w/index.php?title=Courant%E2%80%93Friedrichs%E2%80%93Lewy_condition&oldid=806430673)-limited timestep \\[Back to [top](#toc)\\]\n",
"$$\\label{cfl}$$\n",
"\n",
"In order for our explicit-timestepping numerical solution to Maxwell's equations to be stable, it must satisfy the [CFL](https://en.wikipedia.org/w/index.php?title=Courant%E2%80%93Friedrichs%E2%80%93Lewy_condition&oldid=806430673) condition:\n",
"$$\n",
"\\Delta t \\le \\frac{\\min(ds_i)}{c},\n",
"$$\n",
"where $c$ is the wavespeed, and\n",
"$$ds_i = h_i \\Delta x^i$$ \n",
"is the proper distance between neighboring gridpoints in the $i$th direction (in 3D, there are 3 directions), $h_i$ is the $i$th reference metric scale factor, and $\\Delta x^i$ is the uniform grid spacing in the $i$th direction:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:44.833983Z",
"iopub.status.busy": "2021-06-15T11:39:44.833460Z",
"iopub.status.idle": "2021-06-15T11:39:44.835586Z",
"shell.execute_reply": "2021-06-15T11:39:44.835080Z"
}
},
"outputs": [],
"source": [
"# Output the find_timestep() function to a C file.\n",
"rfm.out_timestep_func_to_file(os.path.join(Ccodesdir,\"find_timestep.h\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"# Step 2: Generate symbolic expressions and output C code for evolving Maxwell's equations \\[Back to [top](#toc)\\]\n",
"$$\\label{mw}$$\n",
"\n",
"Here we read in the symbolic expressions from the NRPy+ [InitialData](../edit/Maxwell/InitialData.py) and [Maxwell/VacuumMaxwell_Flat_Evol_Curvilinear_rescaled](../edit/Maxwell/VacuumMaxwell_Flat_Evol_Curvilinear_rescaled.py) modules to define the initial data, evolution equations, and constraint equations.\n",
"\n",
"\n",
"\n",
"## Step 2.a: Generate symbolic expressions for toroidal dipole field initial data \\[Back to [top](#toc)\\]\n",
"$$\\label{mwid}$$\n",
"\n",
"\n",
"\n",
"Here we use the NRPy+ [InitialData](../edit/Maxwell/InitialData.py) module, described in [this tutorial](Tutorial-VacuumMaxwell_InitialData.ipynb), to write initial data to the grid functions for both systems.\n",
"\n",
"We define the rescaled quantities $a^i$ and $e^i$ in terms of $A^i$ and $E^i$ in curvilinear coordinates within the NRPy+ [InitialData](../edit/Maxwell/InitialData.py) module (see [this tutorial](Tutorial-VacuumMaxwell_formulation_Curvilinear.ipynb) for more detail);\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}"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:44.840688Z",
"iopub.status.busy": "2021-06-15T11:39:44.840266Z",
"iopub.status.idle": "2021-06-15T11:39:47.131593Z",
"shell.execute_reply": "2021-06-15T11:39:47.131118Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Currently using System_II initial data\n"
]
}
],
"source": [
"import Maxwell.InitialData as mwid\n",
"\n",
"# Set which system to use, which are defined in Maxwell/InitialData.py\n",
"par.set_parval_from_str(\"Maxwell.InitialData::System_to_use\",\"System_II\")\n",
"\n",
"mwid.InitialData()\n",
"aidU = ixp.zerorank1()\n",
"eidU = ixp.zerorank1()\n",
"for i in range(DIM):\n",
" aidU[i] = mwid.AidU[i]/rfm.ReU[i]\n",
" eidU[i] = mwid.EidU[i]/rfm.ReU[i]\n",
"\n",
"Maxwell_ID_SymbExpressions = [\\\n",
" lhrh(lhs=\"*AU0_exact\",rhs=aidU[0]),\\\n",
" lhrh(lhs=\"*AU1_exact\",rhs=aidU[1]),\\\n",
" lhrh(lhs=\"*AU2_exact\",rhs=aidU[2]),\\\n",
" lhrh(lhs=\"*EU0_exact\",rhs=eidU[0]),\\\n",
" lhrh(lhs=\"*EU1_exact\",rhs=eidU[1]),\\\n",
" lhrh(lhs=\"*EU2_exact\",rhs=eidU[2]),\\\n",
" lhrh(lhs=\"*PSI_exact\",rhs=mwid.psi_ID),\\\n",
" lhrh(lhs=\"*GAMMA_exact\",rhs=mwid.Gamma_ID)]\n",
"\n",
"Maxwell_ID_CcodeKernel = fin.FD_outputC(\"returnstring\", Maxwell_ID_SymbExpressions)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 2.b: Generate symbolic expressions for evolution equations \\[Back to [top](#toc)\\]\n",
"$$\\label{mwevol}$$\n",
"\n",
"Here we use the NRPy+ [Maxwell/VacuumMaxwell_Flat_Evol_Curvilinear_rescaled](../edit/Maxwell/VacuumMaxwell_Flat_Evol_Curvilinear_rescaled.py) module, described in [this tutorial](Tutorial-VacuumMaxwell_Curvilinear_RHSs.ipynb), to ascribe the evolution equations to the grid functions."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:47.136672Z",
"iopub.status.busy": "2021-06-15T11:39:47.136133Z",
"iopub.status.idle": "2021-06-15T11:39:48.638245Z",
"shell.execute_reply": "2021-06-15T11:39:48.637713Z"
}
},
"outputs": [],
"source": [
"import Maxwell.VacuumMaxwell_Flat_Evol_Curvilinear_rescaled as rhs\n",
"\n",
"# Set which system to use, which are defined in Maxwell/InitialData.py\n",
"par.set_parval_from_str(\"Maxwell.InitialData::System_to_use\",\"System_II\")\n",
"\n",
"cmd.mkdir(os.path.join(Ccodesdir,\"rfm_files/\"))\n",
"par.set_parval_from_str(\"reference_metric::enable_rfm_precompute\",\"True\")\n",
"par.set_parval_from_str(\"reference_metric::rfm_precompute_Ccode_outdir\",os.path.join(Ccodesdir,\"rfm_files/\"))\n",
"\n",
"rhs.VacuumMaxwellRHSs_rescaled()\n",
"\n",
"Maxwell_RHSs_SymbExpressions = [\\\n",
" lhrh(lhs=gri.gfaccess(\"rhs_gfs\",\"aU0\"),rhs=rhs.arhsU[0]),\\\n",
" lhrh(lhs=gri.gfaccess(\"rhs_gfs\",\"aU1\"),rhs=rhs.arhsU[1]),\\\n",
" lhrh(lhs=gri.gfaccess(\"rhs_gfs\",\"aU2\"),rhs=rhs.arhsU[2]),\\\n",
" lhrh(lhs=gri.gfaccess(\"rhs_gfs\",\"eU0\"),rhs=rhs.erhsU[0]),\\\n",
" lhrh(lhs=gri.gfaccess(\"rhs_gfs\",\"eU1\"),rhs=rhs.erhsU[1]),\\\n",
" lhrh(lhs=gri.gfaccess(\"rhs_gfs\",\"eU2\"),rhs=rhs.erhsU[2]),\\\n",
" lhrh(lhs=gri.gfaccess(\"rhs_gfs\",\"psi\"),rhs=rhs.psi_rhs),\\\n",
" lhrh(lhs=gri.gfaccess(\"rhs_gfs\",\"Gamma\"),rhs=rhs.Gamma_rhs)]\n",
"\n",
"par.set_parval_from_str(\"reference_metric::enable_rfm_precompute\",\"False\") # Reset to False to disable rfm_precompute.\n",
"rfm.ref_metric__hatted_quantities()\n",
"\n",
"Maxwell_RHSs_string = fin.FD_outputC(\"returnstring\",\n",
" Maxwell_RHSs_SymbExpressions,\n",
" params=\"enable_SIMD=True\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 2.c: Generate symbolic expressions for constraint equations \\[Back to [top](#toc)\\]\n",
"$$\\label{mwcon}$$\n",
"\n",
"We now use the NRPy+ [Maxwell/VacuumMaxwell_Flat_Evol_Curvilinear_rescaled](../edit/Maxwell/VacuumMaxwell_Flat_Evol_Curvilinear_rescaled.py) module, described in [this tutorial](Tutorial-VacuumMaxwell_Curvilinear_RHSs.ipynb), to ascribe the constraint equations."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:48.691216Z",
"iopub.status.busy": "2021-06-15T11:39:48.655465Z",
"iopub.status.idle": "2021-06-15T11:39:48.723718Z",
"shell.execute_reply": "2021-06-15T11:39:48.723267Z"
}
},
"outputs": [],
"source": [
"C = gri.register_gridfunctions(\"AUX\", \"C\")\n",
"G = gri.register_gridfunctions(\"AUX\", \"G\")\n",
"\n",
"Constraints_string = fin.FD_outputC(\"returnstring\",\n",
" [lhrh(lhs=gri.gfaccess(\"aux_gfs\", \"C\"), rhs=rhs.C),\n",
" lhrh(lhs=gri.gfaccess(\"aux_gfs\", \"G\"), rhs=rhs.G)],\n",
" params=\"outCverbose=False\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 2.d: Generate symbolic expressions for converting $A^i$ and $E^i$ to the Cartesian basis \\[Back to [top](#toc)\\]\n",
"$$\\label{mwcart}$$\n",
"\n",
"We now use the NRPy+ [Maxwell/VacuumMaxwell_Flat_Evol_Curvilinear_rescaled](../edit/Maxwell/VacuumMaxwell_Flat_Evol_Curvilinear_rescaled.py) module, described in [this tutorial](Tutorial-VacuumMaxwell_Curvilinear_RHSs.ipynb), to ascribe the coordinate conversion, to make our convergence tests slightly easier."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:48.785991Z",
"iopub.status.busy": "2021-06-15T11:39:48.761152Z",
"iopub.status.idle": "2021-06-15T11:39:48.788029Z",
"shell.execute_reply": "2021-06-15T11:39:48.787574Z"
}
},
"outputs": [],
"source": [
"AUCart = ixp.register_gridfunctions_for_single_rank1(\"AUX\", \"AUCart\")\n",
"EUCart = ixp.register_gridfunctions_for_single_rank1(\"AUX\", \"EUCart\")\n",
"\n",
"Cartesian_Vectors_string = fin.FD_outputC(\"returnstring\",\n",
" [lhrh(lhs=gri.gfaccess(\"aux_gfs\", \"AUCart0\"), rhs=rhs.AU_Cart[0]),\n",
" lhrh(lhs=gri.gfaccess(\"aux_gfs\", \"AUCart1\"), rhs=rhs.AU_Cart[1]),\n",
" lhrh(lhs=gri.gfaccess(\"aux_gfs\", \"AUCart2\"), rhs=rhs.AU_Cart[2]),\n",
" lhrh(lhs=gri.gfaccess(\"aux_gfs\", \"EUCart0\"), rhs=rhs.EU_Cart[0]),\n",
" lhrh(lhs=gri.gfaccess(\"aux_gfs\", \"EUCart1\"), rhs=rhs.EU_Cart[1]),\n",
" lhrh(lhs=gri.gfaccess(\"aux_gfs\", \"EUCart2\"), rhs=rhs.EU_Cart[2])],\n",
" params=\"outCverbose=False\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 2.e: Output C codes for initial data and evolution equations \\[Back to [top](#toc)\\]\n",
"$$\\label{mwccode}$$\n",
"\n",
"Next we write the C codes for the initial data and evolution equations to files, to be used later by our main C code."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:48.792628Z",
"iopub.status.busy": "2021-06-15T11:39:48.792088Z",
"iopub.status.idle": "2021-06-15T11:39:48.795171Z",
"shell.execute_reply": "2021-06-15T11:39:48.794721Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Output C function exact_solution_single_point() to file MaxwellEvolCurvi_Playground_Ccodes/exact_solution_single_point.h\n",
"Output C function exact_solution_all_points() to file MaxwellEvolCurvi_Playground_Ccodes/exact_solution_all_points.h\n",
"Output C function rhs_eval() to file MaxwellEvolCurvi_Playground_Ccodes/rhs_eval.h\n"
]
}
],
"source": [
"# Step 11: Generate all needed C functions\n",
"Part_P1_body = Maxwell_ID_CcodeKernel\n",
"desc=\"Part P1: Declare the function for the exact solution at a single point. time==0 corresponds to the initial data.\"\n",
"name=\"exact_solution_single_point\"\n",
"outCfunction(\n",
" outfile = os.path.join(Ccodesdir,name+\".h\"), desc=desc, name=name,\n",
" params =\"const REAL xx0,const REAL xx1,const REAL xx2,const paramstruct *restrict params,\\\n",
" REAL *EU0_exact, \\\n",
" REAL *EU1_exact, \\\n",
" REAL *EU2_exact, \\\n",
" REAL *AU0_exact, \\\n",
" REAL *AU1_exact, \\\n",
" REAL *AU2_exact, \\\n",
" REAL *PSI_exact,\\\n",
" REAL *GAMMA_exact\",\n",
" body = Part_P1_body,\n",
" loopopts = \"\")\n",
"\n",
"desc=\"Part P2: Declare the function for the exact solution at all points. time==0 corresponds to the initial data.\"\n",
"name=\"exact_solution_all_points\"\n",
"outCfunction(\n",
" outfile = os.path.join(Ccodesdir,name+\".h\"), desc=desc, name=name,\n",
" params =\"const paramstruct *restrict params,REAL *restrict xx[3], REAL *restrict in_gfs\",\n",
" body =\"\"\"\n",
"REAL xx0 = xx[0][i0]; REAL xx1 = xx[1][i1]; REAL xx2 = xx[2][i2];\n",
"exact_solution_single_point(xx0,xx1,xx2,params,&in_gfs[IDX4S(EU0GF,i0,i1,i2)],\n",
" &in_gfs[IDX4S(EU1GF,i0,i1,i2)],\n",
" &in_gfs[IDX4S(EU2GF,i0,i1,i2)],\n",
" &in_gfs[IDX4S(AU0GF,i0,i1,i2)],\n",
" &in_gfs[IDX4S(AU1GF,i0,i1,i2)],\n",
" &in_gfs[IDX4S(AU2GF,i0,i1,i2)],\n",
" &in_gfs[IDX4S(PSIGF,i0,i1,i2)],\n",
" &in_gfs[IDX4S(GAMMAGF,i0,i1,i2)]);\"\"\",\n",
" loopopts = \"AllPoints\")\n",
"\n",
"Part_P3_body = Maxwell_RHSs_string\n",
"\n",
"desc=\"Part P3: Declare the function to evaluate the RHSs of Maxwell's equations\"\n",
"name=\"rhs_eval\"\n",
"outCfunction(\n",
" outfile = os.path.join(Ccodesdir,name+\".h\"), desc=desc, name=name,\n",
" params =\"\"\"rfm_struct *restrict rfmstruct,const paramstruct *restrict params,\n",
" const REAL *restrict in_gfs, REAL *restrict rhs_gfs\"\"\",\n",
" body =Part_P3_body,\n",
" loopopts = \"InteriorPoints,enable_SIMD,enable_rfm_precompute\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 2.f: Output C code for constraint equations \\[Back to [top](#toc)\\]\n",
"$$\\label{mwccode_con}$$\n",
"\n",
"Finally output the C code for evaluating the divergence constraint, described in [this tutorial](Tutorial-VacuumMaxwell_Curvilinear_RHSs.ipynb). In the absence of numerical error, this constraint should evaluate to zero, but due to numerical (typically truncation and roundoff) error it does not. We will therefore measure the divergence constraint violation to gauge the accuracy of our simulation, and ultimately determine whether errors are dominated by numerical finite differencing (truncation) error as expected. Specifically, we take the L2 norm of the constraint violation, via\n",
"\n",
"\\begin{align}\n",
" \\lVert C \\rVert^2 &= \\frac{\\int C^2 d\\mathcal{V}}{\\int d\\mathcal{V}}.\n",
"\\end{align}\n",
"\n",
"Numerically approximating this integral, in spherical coordinates for example, then gives us\n",
"\n",
"\\begin{align}\n",
" \\lVert C \\rVert^2 &= \\frac{\\sum C^2 r^2 \\sin^2 (\\theta) dr d\\theta d\\phi}{\\sum r^2 \\sin^2 (\\theta) dr d\\theta d\\phi}, \\\\ \\\\\n",
" &= \\frac{\\sum C^2 r^2 \\sin^2 (\\theta)}{\\sum r^2 \\sin^2 (\\theta) } , \\\\ \\\\\n",
" &= \\frac{\\sum C^2 \\ \\sqrt{\\text{det} \\ \\hat{\\gamma}}}{\\sum \\sqrt{\\text{det} \\ \\hat{\\gamma}}},\n",
"\\end{align}\n",
"\n",
"where $\\hat{\\gamma}$ is the reference metric. Thus, along with the C code to calculate the constraints, we also print out the code required to evaluate $\\sqrt{\\text{det} \\ \\hat{\\gamma}}$ at any given point."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:48.809454Z",
"iopub.status.busy": "2021-06-15T11:39:48.799155Z",
"iopub.status.idle": "2021-06-15T11:39:48.816742Z",
"shell.execute_reply": "2021-06-15T11:39:48.816353Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Output C function Constraints() to file MaxwellEvolCurvi_Playground_Ccodes/Constraints.h\n",
"Output C function diagnostic_integrand() to file MaxwellEvolCurvi_Playground_Ccodes/diagnostic_integrand.h\n"
]
}
],
"source": [
"# Set up the C function for the calculating the constraints\n",
"Part_P4_body = Constraints_string\n",
"desc=\"Evaluate the constraints\"\n",
"name=\"Constraints\"\n",
"outCfunction(\n",
" outfile = os.path.join(Ccodesdir,name+\".h\"), desc=desc, name=name,\n",
" params = \"\"\"rfm_struct *restrict rfmstruct,const paramstruct *restrict params,\n",
" REAL *restrict in_gfs, REAL *restrict aux_gfs\"\"\",\n",
" body = Part_P4_body,\n",
" loopopts = \"InteriorPoints,enable_rfm_precompute\")\n",
"\n",
"# intgrand to be used to calculate the L2 norm of the constraint\n",
"diagnostic_integrand_body = outputC(rfm.detgammahat,\"*detg\",filename='returnstring',\n",
" params=\"includebraces=False\")\n",
"desc=\"Evaluate the volume element at a specific point\"\n",
"name=\"diagnostic_integrand\"\n",
"outCfunction(\n",
" outfile = os.path.join(Ccodesdir,name+\".h\"), desc=desc, name=name,\n",
" params =\"const REAL xx0,const REAL xx1,const REAL xx2,const paramstruct *restrict params, REAL *restrict detg\",\n",
" body = diagnostic_integrand_body,\n",
" loopopts = \"\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 2.g: Output C code for converting $A^i$ and $E^i$ to Cartesian coordinates \\[Back to [top](#toc)\\]\n",
"$$\\label{mwccode_cart}$$\n",
"\n",
"Here we write the C code for the coordinate transformation to Cartesian coordinates."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:48.819376Z",
"iopub.status.busy": "2021-06-15T11:39:48.818945Z",
"iopub.status.idle": "2021-06-15T11:39:48.821441Z",
"shell.execute_reply": "2021-06-15T11:39:48.821089Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Output C function Cartesian_basis() to file MaxwellEvolCurvi_Playground_Ccodes/Cartesian_basis.h\n"
]
}
],
"source": [
"desc=\"Convert EU and AU to Cartesian basis\"\n",
"name=\"Cartesian_basis\"\n",
"outCfunction(\n",
" outfile = os.path.join(Ccodesdir,name+\".h\"), desc=desc, name=name,\n",
" params = \"\"\"rfm_struct *restrict rfmstruct,const paramstruct *restrict params, REAL *restrict xx[3],\n",
" REAL *restrict in_gfs, REAL *restrict aux_gfs\"\"\",\n",
" body = \"REAL xx0 = xx[0][i0]; REAL xx1 = xx[1][i1]; REAL xx2 = xx[2][i2];\\n\"+Cartesian_Vectors_string,\n",
" loopopts = \"AllPoints, enable_rfm_precompute\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 2.h: Output C code for printing 2D data \\[Back to [top](#toc)\\]\n",
"$$\\label{mwccode_xzloop}$$\n",
"\n",
"Here we output the neccesary C code to print out a 2D slice of the data in the xz-plane, using the `xz_loop` macro"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:48.824858Z",
"iopub.status.busy": "2021-06-15T11:39:48.824459Z",
"iopub.status.idle": "2021-06-15T11:39:48.826575Z",
"shell.execute_reply": "2021-06-15T11:39:48.826221Z"
}
},
"outputs": [],
"source": [
"def xz_loop(CoordSystem):\n",
" ret = \"\"\"// xz-plane output for \"\"\" + CoordSystem + r\"\"\" coordinates:\n",
"#define LOOP_XZ_PLANE(ii, jj, kk) \\\n",
"\"\"\"\n",
" if \"Spherical\" in CoordSystem or \"SymTP\" in CoordSystem:\n",
" ret += r\"\"\"for (int i2 = 0; i2 < Nxx_plus_2NGHOSTS2; i2++) \\\n",
" if(i2 == NGHOSTS || i2 == Nxx_plus_2NGHOSTS2/2) \\\n",
" for (int i1 = 0; i1 < Nxx_plus_2NGHOSTS1; i1++) \\\n",
" for (int i0 = 0; i0 < Nxx_plus_2NGHOSTS0; i0++)\n",
"\"\"\"\n",
" elif \"Cylindrical\" in CoordSystem:\n",
" ret += r\"\"\"for (int i2 = 0; i2 < Nxx_plus_2NGHOSTS2; i2++) \\\n",
" for (int i1 = 0; i1 < Nxx_plus_2NGHOSTS1; i1++) \\\n",
" if(i1 == NGHOSTS || i1 == Nxx_plus_2NGHOSTS1/2) \\\n",
" for (int i0 = 0; i0 < Nxx_plus_2NGHOSTS0; i0++)\n",
"\"\"\"\n",
" elif \"Cartesian\" in CoordSystem:\n",
" ret += r\"\"\"for (int i2 = 0; i2 < Nxx_plus_2NGHOSTS2; i2++) \\\n",
" for (int i1 = Nxx_plus_2NGHOSTS1/2; i1 < Nxx_plus_2NGHOSTS1/2+1; i1++) \\\n",
" for (int i0 = 0; i0 < Nxx_plus_2NGHOSTS0; i0++)\n",
"\"\"\"\n",
" return ret\n",
"\n",
"with open(os.path.join(Ccodesdir,\"xz_loop.h\"),\"w\") as file:\n",
" file.write(xz_loop(CoordSystem))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 2.i: Output C codes needed for declaring and setting Cparameters; also set `free_parameters.h` \\[Back to [top](#toc)\\]\n",
"$$\\label{cparams_rfm_and_domainsize}$$\n",
"\n",
"Based on declared NRPy+ Cparameters, first we generate `declare_Cparameters_struct.h`, `set_Cparameters_default.h`, and `set_Cparameters[-SIMD].h`.\n",
"\n",
"Then we output `free_parameters.h`, which sets initial data parameters, as well as grid domain & reference metric parameters, applying `domain_size` and `sinh_width`/`SymTP_bScale` (if applicable) as set above"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:48.830463Z",
"iopub.status.busy": "2021-06-15T11:39:48.830058Z",
"iopub.status.idle": "2021-06-15T11:39:49.128961Z",
"shell.execute_reply": "2021-06-15T11:39:49.128496Z"
}
},
"outputs": [],
"source": [
"# Generate declare_Cparameters_struct.h, set_Cparameters_default.h, and set_Cparameters[-SIMD].h\n",
"par.generate_Cparameters_Ccodes(os.path.join(Ccodesdir))\n",
"\n",
"# Set free_parameters.h\n",
"with open(os.path.join(Ccodesdir,\"free_parameters.h\"),\"w\") as file:\n",
" file.write(\"\"\"\n",
"// Set free-parameter values.\n",
"params.time = 0.0; // Initial simulation time time corresponds to exact solution at time=0.\n",
"params.amp = 1.0;\n",
"params.lam = 1.0;\n",
"params.wavespeed = 1.0;\\n\"\"\")\n",
"\n",
"# Append to $Ccodesdir/free_parameters.h reference metric parameters based on generic\n",
"# domain_size,sinh_width,sinhv2_const_dr,SymTP_bScale,\n",
"# parameters set above.\n",
"rfm.out_default_free_parameters_for_rfm(os.path.join(Ccodesdir,\"free_parameters.h\"),\n",
" domain_size,sinh_width,sinhv2_const_dr,SymTP_bScale)\n",
"\n",
"# Generate set_Nxx_dxx_invdx_params__and__xx.h:\n",
"rfm.set_Nxx_dxx_invdx_params__and__xx_h(Ccodesdir, grid_centering=\"cell\")\n",
"\n",
"# Generate xx_to_Cart.h, which contains xx_to_Cart() for\n",
"# (the mapping from xx->Cartesian) for the chosen CoordSystem:\n",
"rfm.xx_to_Cart_h(\"xx_to_Cart\",\"./set_Cparameters.h\",os.path.join(Ccodesdir,\"xx_to_Cart.h\"))\n",
"\n",
"# Step 3.d.v: Generate declare_Cparameters_struct.h, set_Cparameters_default.h, and set_Cparameters[-SIMD].h\n",
"par.generate_Cparameters_Ccodes(os.path.join(Ccodesdir))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"# Step 3: Set up Sommerfeld boundary condition for Cartesian coordinate system \\[Back to [top](#toc)\\]\n",
"$$\\label{bc_functs}$$\n",
"\n",
"Next we output the C code necessary to implement the Sommerfeld boundary condition in Cartesian coordinates, [as documented in the corresponding NRPy+ tutorial notebook](Tutorial-SommerfeldBoundaryCondition.ipynb)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:49.132524Z",
"iopub.status.busy": "2021-06-15T11:39:49.131988Z",
"iopub.status.idle": "2021-06-15T11:39:49.913555Z",
"shell.execute_reply": "2021-06-15T11:39:49.913015Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wrote to file \"MaxwellEvolCurvi_Playground_Ccodes/boundary_conditions/parity_conditions_symbolic_dot_products.h\"\n",
"Evolved parity: ( Gamma:0, aU0:1, aU1:2, aU2:3, eU0:1, eU1:2, eU2:3, psi:0\n",
" )\n",
"Auxiliary parity: ( AUCart0:1, AUCart1:2, AUCart2:3, C:0, EUCart0:1,\n",
" EUCart1:2, EUCart2:3, G:0 )\n",
"\n",
"Wrote to file \"MaxwellEvolCurvi_Playground_Ccodes/boundary_conditions/EigenCoord_Cart_to_xx.h\"\n",
"\n",
"Successfully generated Sommerfeld boundary condition C code\n"
]
}
],
"source": [
"import CurviBoundaryConditions.CurviBoundaryConditions as cbcs\n",
"cbcs.Set_up_CurviBoundaryConditions(os.path.join(Ccodesdir,\"boundary_conditions/\"),\n",
" Cparamspath=os.path.join(\"../\"),\n",
" BoundaryCondition=BoundaryCondition)\n",
"\n",
"if BoundaryCondition == \"Sommerfeld\":\n",
" bcs = cbcs.sommerfeld_boundary_condition_class(fd_order=4,\n",
" vars_radial_falloff_power_default=3,\n",
" vars_speed_default=1.,\n",
" vars_at_inf_default=0.)\n",
" bcs.write_sommerfeld_file(Ccodesdir)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"# Step 4: `Maxwell_Playground.c`: The Main C Code \\[Back to [top](#toc)\\]\n",
"$$\\label{mainc}$$"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:49.916913Z",
"iopub.status.busy": "2021-06-15T11:39:49.916376Z",
"iopub.status.idle": "2021-06-15T11:39:49.918324Z",
"shell.execute_reply": "2021-06-15T11:39:49.917796Z"
}
},
"outputs": [],
"source": [
"# Part P0: Define REAL, set the number of ghost cells NGHOSTS (from NRPy+'s FD_CENTDERIVS_ORDER),\n",
"# and set the CFL_FACTOR (which can be overwritten at the command line)\n",
"\n",
"with open(os.path.join(Ccodesdir,\"Maxwell_Playground_REAL__NGHOSTS__CFL_FACTOR.h\"), \"w\") as file:\n",
" file.write(\"\"\"\n",
"// Part P0.a: Set the number of ghost cells, from NRPy+'s FD_CENTDERIVS_ORDER\n",
"#define NGHOSTS \"\"\"+str(int(FD_order/2)+1)+\"\"\"\n",
"// Part P0.b: Set the numerical precision (REAL) to double, ensuring all floating point\n",
"// numbers are stored to at least ~16 significant digits\n",
"#define REAL \"\"\"+REAL+\"\"\"\n",
"// Part P0.c: Set the CFL Factor. Can be overwritten at command line.\n",
"REAL CFL_FACTOR = \"\"\"+str(default_CFL_FACTOR)+\";\")"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:49.923596Z",
"iopub.status.busy": "2021-06-15T11:39:49.923104Z",
"iopub.status.idle": "2021-06-15T11:39:49.925473Z",
"shell.execute_reply": "2021-06-15T11:39:49.925801Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Writing MaxwellEvolCurvi_Playground_Ccodes//Maxwell_Playground.c\n"
]
}
],
"source": [
"%%writefile $Ccodesdir/Maxwell_Playground.c\n",
"\n",
"// Step P0: Define REAL and NGHOSTS; and declare CFL_FACTOR. This header is generated in NRPy+.\n",
"#include \"Maxwell_Playground_REAL__NGHOSTS__CFL_FACTOR.h\"\n",
"\n",
"#include \"rfm_files/rfm_struct__declare.h\"\n",
"\n",
"#include \"declare_Cparameters_struct.h\"\n",
"\n",
"// All SIMD intrinsics used in SIMD-enabled C code loops are defined here:\n",
"#include \"SIMD/SIMD_intrinsics.h\"\n",
"\n",
"// Step P1: Import needed header files\n",
"#include \"stdio.h\"\n",
"#include \"stdlib.h\"\n",
"#include \"math.h\"\n",
"#include \"time.h\"\n",
"#include \"stdint.h\" // Needed for Windows GCC 6.x compatibility\n",
"#ifndef M_PI\n",
"#define M_PI 3.141592653589793238462643383279502884L\n",
"#endif\n",
"#ifndef M_SQRT1_2\n",
"#define M_SQRT1_2 0.707106781186547524400844362104849039L\n",
"#endif\n",
"\n",
"// Step P2: Declare the IDX4S(gf,i,j,k) macro, which enables us to store 4-dimensions of\n",
"// data in a 1D array. In this case, consecutive values of \"i\"\n",
"// (all other indices held to a fixed value) are consecutive in memory, where\n",
"// consecutive values of \"j\" (fixing all other indices) are separated by\n",
"// Nxx_plus_2NGHOSTS0 elements in memory. Similarly, consecutive values of\n",
"// \"k\" are separated by Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1 in memory, etc.\n",
"#define IDX4S(g,i,j,k) \\\n",
"( (i) + Nxx_plus_2NGHOSTS0 * ( (j) + Nxx_plus_2NGHOSTS1 * ( (k) + Nxx_plus_2NGHOSTS2 * (g) ) ) )\n",
"#define IDX4ptS(g,idx) ( (idx) + (Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2) * (g) )\n",
"#define IDX3S(i,j,k) ( (i) + Nxx_plus_2NGHOSTS0 * ( (j) + Nxx_plus_2NGHOSTS1 * ( (k) ) ) )\n",
"#define LOOP_REGION(i0min,i0max, i1min,i1max, i2min,i2max) \\\n",
" for(int i2=i2min;i2Cartesian via\n",
"// {xx[0][i0],xx[1][i1],xx[2][i2]}->{xCart[0],xCart[1],xCart[2]}\n",
"\n",
"#include \"xx_to_Cart.h\"\n",
"// main() function:\n",
"// Step 0: Read command-line input, set up grid structure, allocate memory for gridfunctions, set up coordinates\n",
"// Step 1: Set up initial data to an exact solution\n",
"// Step 2: Start the timer, for keeping track of how fast the simulation is progressing.\n",
"// Step 3: Integrate the initial data forward in time using the chosen RK-like Method of\n",
"// Lines timestepping algorithm, and output periodic simulation diagnostics\n",
"// Step 3.a: Output 2D data file periodically, for visualization\n",
"// Step 3.b: Step forward one timestep (t -> t+dt) in time using\n",
"// chosen RK-like MoL timestepping algorithm\n",
"// Step 3.c: If t=t_final, output x and y components of evolution variables and the\n",
"// constraint violation to 2D data file\n",
"// Step 3.d: Progress indicator printing to stderr\n",
"// Step 4: Free all allocated memory\n",
"int main(int argc, const char *argv[]) {\n",
" paramstruct params;\n",
"#include \"set_Cparameters_default.h\"\n",
"\n",
" // Step 0a: Read command-line input, error out if nonconformant\n",
" if((argc != 5 && argc != 6) || atoi(argv[1]) < NGHOSTS || atoi(argv[2]) < NGHOSTS || atoi(argv[3]) < 2 /* FIXME; allow for axisymmetric sims */) {\n",
" fprintf(stderr,\"Error: Expected three command-line arguments: ./Maxwell_Playground Nx0 Nx1 Nx2,\\n\");\n",
" fprintf(stderr,\"where Nx[0,1,2] is the number of grid points in the 0, 1, and 2 directions.\\n\");\n",
" fprintf(stderr,\"Nx[] MUST BE larger than NGHOSTS (= %d)\\n\",NGHOSTS);\n",
" exit(1);\n",
" }\n",
" if(argc == 5) {\n",
" CFL_FACTOR = strtod(argv[5],NULL);\n",
" if(CFL_FACTOR > 0.5 && atoi(argv[3])!=2) {\n",
" fprintf(stderr,\"WARNING: CFL_FACTOR was set to %e, which is > 0.5.\\n\",CFL_FACTOR);\n",
" fprintf(stderr,\" This will generally only be stable if the simulation is purely axisymmetric\\n\");\n",
" fprintf(stderr,\" However, Nx2 was set to %d>2, which implies a non-axisymmetric simulation\\n\",atoi(argv[3]));\n",
" }\n",
" }\n",
" // Step 0b: Set up numerical grid structure, first in space...\n",
" const int Nxx[3] = { atoi(argv[1]), atoi(argv[2]), atoi(argv[3]) };\n",
" if(Nxx[0]%2 != 0 || Nxx[1]%2 != 0 || Nxx[2]%2 != 0) {\n",
" fprintf(stderr,\"Error: Cannot guarantee a proper cell-centered grid if number of grid cells not set to even number.\\n\");\n",
" fprintf(stderr,\" For example, in case of angular directions, proper symmetry zones will not exist.\\n\");\n",
" exit(1);\n",
" }\n",
"\n",
" // Step 0c: Set free parameters, overwriting Cparameters defaults\n",
" // by hand or with command-line input, as desired.\n",
"#include \"free_parameters.h\"\n",
"\n",
" // Step 0d: Uniform coordinate grids are stored to *xx[3]\n",
" REAL *xx[3];\n",
" // Step 0d.i: Set bcstruct\n",
" bc_struct bcstruct;\n",
" {\n",
" int EigenCoord = 1;\n",
" // Step 0d.ii: Call set_Nxx_dxx_invdx_params__and__xx(), which sets\n",
" // params Nxx,Nxx_plus_2NGHOSTS,dxx,invdx, and xx[] for the\n",
" // chosen Eigen-CoordSystem.\n",
" set_Nxx_dxx_invdx_params__and__xx(EigenCoord, Nxx, ¶ms, xx);\n",
" // Step 0d.iii: Set Nxx_plus_2NGHOSTS_tot\n",
"#include \"set_Cparameters-nopointer.h\"\n",
" const int Nxx_plus_2NGHOSTS_tot = Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2;\n",
" // Step 0e: Find ghostzone mappings; set up bcstruct\n",
"#include \"boundary_conditions/driver_bcstruct.h\"\n",
" // Step 0e.i: Free allocated space for xx[][] array\n",
" for(int i=0;i<3;i++) free(xx[i]);\n",
" }\n",
"\n",
" // Step 0f: Call set_Nxx_dxx_invdx_params__and__xx(), which sets\n",
" // params Nxx,Nxx_plus_2NGHOSTS,dxx,invdx, and xx[] for the\n",
" // chosen (non-Eigen) CoordSystem.\n",
" int EigenCoord = 0;\n",
" set_Nxx_dxx_invdx_params__and__xx(EigenCoord, Nxx, ¶ms, xx);\n",
"\n",
" // Step 0g: Set all C parameters \"blah\" for params.blah, including\n",
" // Nxx_plus_2NGHOSTS0 = params.Nxx_plus_2NGHOSTS0, etc.\n",
"#include \"set_Cparameters-nopointer.h\"\n",
" const int Nxx_plus_2NGHOSTS_tot = Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2;\n",
"\n",
" // Step 0h: Time coordinate parameters\n",
" const REAL t_final = strtod(argv[4],NULL);\n",
"\n",
" // Step 0i: Set timestep based on smallest proper distance between gridpoints and CFL factor\n",
" REAL dt = find_timestep(¶ms, xx);\n",
" //fprintf(stderr,\"# Timestep set to = %e\\n\",(double)dt);\n",
" int N_final = (int)(t_final / dt + 0.5); // The number of points in time.\n",
" // Add 0.5 to account for C rounding down\n",
" // typecasts to integers.\n",
" int output_every_N = (int)((REAL)N_final/800.0);\n",
" if(output_every_N == 0) output_every_N = 1;\n",
"\n",
" // Step 0j: Error out if the number of auxiliary gridfunctions outnumber evolved gridfunctions.\n",
" // This is a limitation of the RK method. You are always welcome to declare & allocate\n",
" // additional gridfunctions by hand.\n",
" if(NUM_AUX_GFS > NUM_EVOL_GFS) {\n",
" fprintf(stderr,\"Error: NUM_AUX_GFS > NUM_EVOL_GFS. Either reduce the number of auxiliary gridfunctions,\\n\");\n",
" fprintf(stderr,\" or allocate (malloc) by hand storage for *diagnostic_output_gfs. \\n\");\n",
" exit(1);\n",
" }\n",
"\n",
" // Step 0k: Allocate memory for gridfunctions\n",
"#include \"MoLtimestepping/RK_Allocate_Memory.h\"\n",
" REAL *restrict y_0_gfs = (REAL *)malloc(sizeof(REAL) * NUM_EVOL_GFS * Nxx_plus_2NGHOSTS_tot);\n",
" REAL *restrict diagnostic_output_gfs_0 = (REAL *)malloc(sizeof(REAL) * NUM_AUX_GFS * Nxx_plus_2NGHOSTS_tot);\n",
"\n",
" // Step 0l: Set up precomputed reference metric arrays\n",
" // Step 0l.i: Allocate space for precomputed reference metric arrays.\n",
"#include \"rfm_files/rfm_struct__malloc.h\"\n",
"\n",
" // Step 0l.ii: Define precomputed reference metric arrays.\n",
" {\n",
" #include \"set_Cparameters-nopointer.h\"\n",
" #include \"rfm_files/rfm_struct__define.h\"\n",
" }\n",
"\n",
" LOOP_ALL_GFS_GPS(i) {\n",
" y_n_gfs[i] = 0.0/0.0;\n",
"}\n",
"\n",
" // Step 1: Set up initial data to be exact solution at time=0:\n",
" params.time = 0.0;\n",
" exact_solution_all_points(¶ms, xx, y_n_gfs);\n",
"\n",
" // Step 2: Start the timer, for keeping track of how fast the simulation is progressing.\n",
"#ifdef __linux__ // Use high-precision timer in Linux.\n",
" struct timespec start, end;\n",
" clock_gettime(CLOCK_REALTIME, &start);\n",
"#else // Resort to low-resolution, standards-compliant timer in non-Linux OSs\n",
" // http://www.cplusplus.com/reference/ctime/time/\n",
" time_t start_timer,end_timer;\n",
" time(&start_timer); // Resolution of one second...\n",
"#endif\n",
"\n",
" // Step 3: Integrate the initial data forward in time using the chosen RK-like Method of\n",
" // Lines timestepping algorithm, and output periodic simulation diagnostics\n",
" for(int n=0;n<=N_final+1;n++) { // Main loop to progress forward in time.\n",
"\n",
" // At each timestep, set Constraints to NaN in the grid interior\n",
" LOOP_REGION(NGHOSTS,NGHOSTS+Nxx0,\n",
" NGHOSTS,NGHOSTS+Nxx1,\n",
" NGHOSTS,NGHOSTS+Nxx2) {\n",
" const int idx = IDX3S(i0,i1,i2);\n",
" diagnostic_output_gfs[IDX4ptS(CGF,idx)] = 0.0/0.0;\n",
" }\n",
"\n",
" // Step 3.a: Output 2D data file periodically, for visualization\n",
" params.time = ((REAL)n)*dt;\n",
" // Evaluate Divergence constraint violation\n",
" Constraints(&rfmstruct, ¶ms, y_n_gfs, diagnostic_output_gfs);\n",
" // log_L2_Norm = log10( sqrt[Integral( [numerical - exact]^2 * dV)] )\n",
" REAL L2Norm_sum_C = 0.;\n",
" int sum = 0;\n",
" LOOP_REGION(NGHOSTS,NGHOSTS+Nxx0,\n",
" NGHOSTS,NGHOSTS+Nxx1,\n",
" NGHOSTS,NGHOSTS+Nxx2) {\n",
" const int idx = IDX3S(i0,i1,i2);\n",
" double C = (double)diagnostic_output_gfs[IDX4ptS(CGF,idx)];\n",
" REAL xx0 = xx[0][i0];\n",
" REAL xx1 = xx[1][i1];\n",
" REAL xx2 = xx[2][i2];\n",
" REAL detghat; diagnostic_integrand(xx0, xx1, xx2, ¶ms, &detghat);\n",
" L2Norm_sum_C += C*C*sqrt(detghat);\n",
" sum = sum + sqrt(detghat);\n",
" }\n",
" REAL L2Norm_C = sqrt(L2Norm_sum_C/(sum));\n",
" printf(\"%e %.15e\\n\",params.time, L2Norm_C);\n",
"\n",
" // Step 3.a: Output 2D data file periodically, for visualization\n",
" if(n%20 == 0) {\n",
" exact_solution_all_points(¶ms, xx, y_0_gfs);\n",
" Cartesian_basis(&rfmstruct, ¶ms, xx, y_n_gfs, diagnostic_output_gfs);\n",
" Cartesian_basis(&rfmstruct, ¶ms, xx, y_0_gfs, diagnostic_output_gfs_0);\n",
" char filename[100];\n",
" sprintf(filename,\"out%d-%08d.txt\",Nxx[0],n);\n",
" FILE *out2D = fopen(filename, \"w\");\n",
" LOOP_XZ_PLANE(ii, jj, kk){\n",
" REAL xCart[3];\n",
" xx_to_Cart(¶ms,xx,i0,i1,i2,xCart);\n",
" int idx = IDX3S(i0,i1,i2);\n",
" REAL Ex_num = (double)diagnostic_output_gfs[IDX4ptS(EUCART0GF,idx)];\n",
" REAL Ey_num = (double)diagnostic_output_gfs[IDX4ptS(EUCART1GF,idx)];\n",
" REAL Ax_num = (double)diagnostic_output_gfs[IDX4ptS(AUCART0GF,idx)];\n",
" REAL Ay_num = (double)diagnostic_output_gfs[IDX4ptS(AUCART1GF,idx)];\n",
" double C = (double)diagnostic_output_gfs[IDX4ptS(CGF,idx)];\n",
"\n",
" fprintf(out2D,\"%e %e %e %.15e %.15e %.15e %.15e %.15e\\n\", params.time,\n",
" xCart[0],xCart[2], Ex_num, Ey_num, Ax_num, Ay_num, C);\n",
" }\n",
" fclose(out2D);\n",
" }\n",
"\n",
" if(n==N_final-1) {\n",
" exact_solution_all_points(¶ms, xx, y_0_gfs);\n",
" Cartesian_basis(&rfmstruct, ¶ms, xx, y_n_gfs, diagnostic_output_gfs);\n",
" Cartesian_basis(&rfmstruct, ¶ms, xx, y_0_gfs, diagnostic_output_gfs_0);\n",
" char filename[100];\n",
" sprintf(filename,\"out%d.txt\",Nxx[0]);\n",
" FILE *out2D = fopen(filename, \"w\");\n",
" LOOP_XZ_PLANE(ii, jj, kk){\n",
" REAL xCart[3];\n",
" xx_to_Cart(¶ms,xx,i0,i1,i2,xCart);\n",
" int idx = IDX3S(i0,i1,i2);\n",
" REAL Ex_num = (double)diagnostic_output_gfs[IDX4ptS(EUCART0GF,idx)];\n",
" REAL Ey_num = (double)diagnostic_output_gfs[IDX4ptS(EUCART1GF,idx)];\n",
"\n",
" REAL Ax_num = (double)diagnostic_output_gfs[IDX4ptS(AUCART0GF,idx)];\n",
" REAL Ay_num = (double)diagnostic_output_gfs[IDX4ptS(AUCART1GF,idx)];\n",
"\n",
" REAL Ex_exact = (double)diagnostic_output_gfs_0[IDX4ptS(EUCART0GF,idx)];\n",
" REAL Ey_exact = (double)diagnostic_output_gfs_0[IDX4ptS(EUCART1GF,idx)];\n",
"\n",
" REAL Ax_exact = (double)diagnostic_output_gfs_0[IDX4ptS(AUCART0GF,idx)];\n",
" REAL Ay_exact = (double)diagnostic_output_gfs_0[IDX4ptS(AUCART1GF,idx)];\n",
"\n",
" REAL Ex__E_rel = log10(fabs(Ex_num - Ex_exact));\n",
" REAL Ey__E_rel = log10(fabs(Ey_num - Ey_exact));\n",
" REAL Ax__E_rel = log10(fabs(Ax_num - Ax_exact));\n",
" REAL Ay__E_rel = log10(fabs(Ay_num - Ay_exact));\n",
"\n",
" fprintf(out2D,\"%e %e %.15e %.15e %.15e %.15e\\n\",xCart[0],xCart[2],\n",
" Ex__E_rel, Ey__E_rel, Ax__E_rel, Ay__E_rel);\n",
" }\n",
" fclose(out2D);\n",
" }\n",
" // Step 3.b: Step forward one timestep (t -> t+dt) in time using\n",
" // chosen RK-like MoL timestepping algorithm\n",
"#include \"MoLtimestepping/RK_MoL.h\"\n",
"\n",
"\n",
" // Step 3.d: Progress indicator printing to stderr\n",
"\n",
" // Step 3.d.i: Measure average time per iteration\n",
"#ifdef __linux__ // Use high-precision timer in Linux.\n",
" clock_gettime(CLOCK_REALTIME, &end);\n",
" const long long unsigned int time_in_ns = 1000000000L * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;\n",
"#else // Resort to low-resolution, standards-compliant timer in non-Linux OSs\n",
" time(&end_timer); // Resolution of one second...\n",
" REAL time_in_ns = difftime(end_timer,start_timer)*1.0e9+0.5; // Round up to avoid divide-by-zero.\n",
"#endif\n",
" const REAL s_per_iteration_avg = ((REAL)time_in_ns / (REAL)n) / 1.0e9;\n",
"\n",
" const int iterations_remaining = N_final - n;\n",
" const REAL time_remaining_in_mins = s_per_iteration_avg * (REAL)iterations_remaining / 60.0;\n",
"\n",
" const REAL num_RHS_pt_evals = (REAL)(Nxx[0]*Nxx[1]*Nxx[2]) * 4.0 * (REAL)n; // 4 RHS evals per gridpoint for RK4\n",
" const REAL RHS_pt_evals_per_sec = num_RHS_pt_evals / ((REAL)time_in_ns / 1.0e9);\n",
"\n",
" // Step 3.d.ii: Output simulation progress to stderr\n",
" if(n % 10 == 0) {\n",
" fprintf(stderr,\"%c[2K\", 27); // Clear the line\n",
" fprintf(stderr,\"It: %d t=%.2f dt=%.2e | %.1f%%; ETA %.0f s | t/h %.2f | gp/s %.2e\\r\", // \\r is carriage return, move cursor to the beginning of the line\n",
" n, n * (double)dt, (double)dt, (double)(100.0 * (REAL)n / (REAL)N_final),\n",
" (double)time_remaining_in_mins*60, (double)(dt * 3600.0 / s_per_iteration_avg), (double)RHS_pt_evals_per_sec);\n",
" fflush(stderr); // Flush the stderr buffer\n",
" } // End progress indicator if(n % 10 == 0)\n",
"\n",
" } // End main loop to progress forward in time.\n",
" fprintf(stderr,\"\\n\"); // Clear the final line of output from progress indicator.\n",
"\n",
" // Step 4: Free all allocated memory\n",
"#include \"rfm_files/rfm_struct__freemem.h\"\n",
"#include \"boundary_conditions/bcstruct_freemem.h\"\n",
"#include \"MoLtimestepping/RK_Free_Memory.h\"\n",
" free(y_0_gfs);\n",
" free(diagnostic_output_gfs_0);\n",
" for(int i=0;i<3;i++) free(xx[i]);\n",
"\n",
" return 0;\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"# Step 5: Compile generated C codes & perform simulation of the propagating toriodal electromagnetic field \\[Back to [top](#toc)\\]\n",
"$$\\label{compileexec}$$\n",
"\n",
"To aid in the cross-platform-compatible (with Windows, MacOS, & Linux) compilation and execution, we make use of `cmdline_helper` [(**Tutorial**)](Tutorial-cmdline_helper.ipynb)."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:49.930854Z",
"iopub.status.busy": "2021-06-15T11:39:49.930432Z",
"iopub.status.idle": "2021-06-15T11:39:51.151759Z",
"shell.execute_reply": "2021-06-15T11:39:51.152253Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Compiling executable...\n",
"(EXEC): Executing `gcc -std=gnu99 -Ofast -fopenmp -march=native -funroll-loops MaxwellEvolCurvi_Playground_Ccodes/Maxwell_Playground.c -o MaxwellEvolCurvi_Playground_Ccodes/output/Maxwell_Playground -lm`...\n",
"(BENCH): Finished executing in 1.2078261375427246 seconds.\n",
"Finished compilation.\n"
]
}
],
"source": [
"import cmdline_helper as cmd\n",
"CFL_FACTOR=0.5\n",
"cmd.C_compile(os.path.join(Ccodesdir,\"Maxwell_Playground.c\"),\n",
" os.path.join(outdir,\"Maxwell_Playground\"),compile_mode=\"optimized\")"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:51.155796Z",
"iopub.status.busy": "2021-06-15T11:39:51.154938Z",
"iopub.status.idle": "2021-06-15T11:39:51.157008Z",
"shell.execute_reply": "2021-06-15T11:39:51.156413Z"
}
},
"outputs": [],
"source": [
"# Change to output directory\n",
"os.chdir(outdir)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:51.160600Z",
"iopub.status.busy": "2021-06-15T11:39:51.159436Z",
"iopub.status.idle": "2021-06-15T11:39:51.175079Z",
"shell.execute_reply": "2021-06-15T11:39:51.174729Z"
}
},
"outputs": [],
"source": [
"# Clean up existing output files\n",
"cmd.delete_existing_files(\"out*.txt\")\n",
"cmd.delete_existing_files(\"out*.png\")\n",
"cmd.delete_existing_files(\"out-*resolution.txt\")"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:51.181804Z",
"iopub.status.busy": "2021-06-15T11:39:51.181185Z",
"iopub.status.idle": "2021-06-15T11:39:55.631192Z",
"shell.execute_reply": "2021-06-15T11:39:55.631541Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(EXEC): Executing `taskset -c 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ./Maxwell_Playground 50 4 100 5.0 0.5`...\n",
"\u001b[2KIt: 150 t=4.87 dt=3.25e-02 | 97.4%; ETA 0 s | t/h 17221.08 | gp/s 1.18e+07\n",
"(BENCH): Finished executing in 1.2078168392181396 seconds.\n",
"(EXEC): Executing `taskset -c 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ./Maxwell_Playground 80 4 160 5.0 0.5`...\n",
"\u001b[2KIt: 240 t=4.87 dt=2.03e-02 | 97.6%; ETA 0 s | t/h 5779.42 | gp/s 1.62e+07\n",
"(BENCH): Finished executing in 3.213651418685913 seconds.\n"
]
}
],
"source": [
"# Set tme to end simulation\n",
"t_final = str(0.5*domain_size) + ' '\n",
"\n",
"# Run executables\n",
"if 'Spherical' in CoordSystem or 'SymTP' in CoordSystem:\n",
" cmd.Execute(\"Maxwell_Playground\", \"64 48 4 \"+t_final+str(CFL_FACTOR), \"out-lowresolution.txt\")\n",
" cmd.Execute(\"Maxwell_Playground\", \"96 72 4 \"+t_final+str(CFL_FACTOR), \"out-medresolution.txt\")\n",
" Nxx0_low = '64'\n",
" Nxx0_med = '96'\n",
"\n",
"elif 'Cylindrical' in CoordSystem:\n",
" cmd.Execute(\"Maxwell_Playground\", \"50 4 100 \"+t_final+str(CFL_FACTOR), \"out-lowresolution.txt\")\n",
" cmd.Execute(\"Maxwell_Playground\", \"80 4 160 \"+t_final+str(CFL_FACTOR), \"out-medresolution.txt\")\n",
" Nxx0_low = '50'\n",
" Nxx0_med = '80'\n",
"\n",
"else:\n",
" # Cartesian\n",
" cmd.Execute(\"Maxwell_Playground\", \"64 64 64 \"+t_final+str(CFL_FACTOR), \"out-lowresolution.txt\")\n",
" cmd.Execute(\"Maxwell_Playground\", \"128 128 128 \"+t_final+str(CFL_FACTOR), \"out-medresolution.txt\")\n",
" Nxx0_low = '64'\n",
" Nxx0_med = '128'"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:55.634591Z",
"iopub.status.busy": "2021-06-15T11:39:55.634195Z",
"iopub.status.idle": "2021-06-15T11:39:55.636485Z",
"shell.execute_reply": "2021-06-15T11:39:55.636083Z"
},
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Finished this code cell.\n"
]
}
],
"source": [
"# Return to root directory\n",
"os.chdir(os.path.join(\"../../\"))\n",
"\n",
"print(\"Finished this code cell.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"# Step 6: Visualize the output! \\[Back to [top](#toc)\\]\n",
"$$\\label{visualize}$$ \n",
"\n",
"In this section we will generate a movie, plotting the x component of the electric field on a 2D grid.."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 6.a: Install `scipy` and download `ffmpeg` if they are not yet installed/downloaded \\[Back to [top](#toc)\\]\n",
"$$\\label{installdownload}$$ \n",
"\n",
"Note that if you are not running this within `mybinder`, but on a Windows system, `ffmpeg` must be installed using a separate package (on [this site](http://ffmpeg.org/)), or if running Jupyter within Anaconda, use the command: `conda install -c conda-forge ffmpeg`."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:55.648607Z",
"iopub.status.busy": "2021-06-15T11:39:55.646374Z",
"iopub.status.idle": "2021-06-15T11:39:56.266808Z",
"shell.execute_reply": "2021-06-15T11:39:56.267280Z"
}
},
"outputs": [],
"source": [
"!pip install scipy > /dev/null\n",
"\n",
"check_for_ffmpeg = !which ffmpeg >/dev/null && echo $?\n",
"if check_for_ffmpeg != ['0']:\n",
" print(\"Couldn't find ffmpeg, so I'll download it.\")\n",
" # Courtesy https://johnvansickle.com/ffmpeg/\n",
" !wget http://astro.phys.wvu.edu/zetienne/ffmpeg-static-amd64-johnvansickle.tar.xz\n",
" !tar Jxf ffmpeg-static-amd64-johnvansickle.tar.xz\n",
" print(\"Copying ffmpeg to ~/.local/bin/. Assumes ~/.local/bin is in the PATH.\")\n",
" !mkdir ~/.local/bin/\n",
" !cp ffmpeg-static-amd64-johnvansickle/ffmpeg ~/.local/bin/\n",
" print(\"If this doesn't work, then install ffmpeg yourself. It should work fine on mybinder.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 6.b: Generate images for visualization animation \\[Back to [top](#toc)\\]\n",
"$$\\label{genimages}$$ \n",
"\n",
"Here we loop through the data files output by the executable compiled and run in [the previous step](#mainc), generating a [png](https://en.wikipedia.org/wiki/Portable_Network_Graphics) image for each data file.\n",
"\n",
"**Special thanks to Terrence Pierre Jacques. His work with the first versions of these scripts greatly contributed to the scripts as they exist below.**"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:39:56.278473Z",
"iopub.status.busy": "2021-06-15T11:39:56.277729Z",
"iopub.status.idle": "2021-06-15T11:40:06.706797Z",
"shell.execute_reply": "2021-06-15T11:40:06.706288Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[2KProcessing file MaxwellEvolCurvi_Playground_Ccodes/output/out80-00000240.txt\r"
]
}
],
"source": [
"## VISUALIZATION ANIMATION, PART 1: Generate PNGs, one per frame of movie ##\n",
"\n",
"import numpy as np\n",
"from scipy.interpolate import griddata\n",
"import matplotlib.pyplot as plt\n",
"from matplotlib.pyplot import savefig\n",
"from IPython.display import HTML\n",
"import matplotlib.image as mgimg\n",
"\n",
"import glob\n",
"import sys\n",
"from matplotlib import animation\n",
"\n",
"globby = glob.glob(os.path.join(outdir,'out'+Nxx0_med+'-00*.txt'))\n",
"file_list = []\n",
"for x in sorted(globby):\n",
" file_list.append(x)\n",
"\n",
"bound = domain_size/2.0\n",
"pl_xmin = -bound\n",
"pl_xmax = +bound\n",
"pl_zmin = -bound\n",
"pl_zmax = +bound\n",
"\n",
"for filename in file_list:\n",
" fig = plt.figure()\n",
" t, x, z, Ex, Ey, Ax, Ay, C = np.loadtxt(filename).T #Transposed for easier unpacking\n",
"\n",
" plotquantity = Ex\n",
" time = np.round(t[0], decimals=3)\n",
" plotdescription = \"Numerical Soln.\"\n",
" plt.title(r\"$E_x$ at $t$ = \"+str(time))\n",
" plt.xlabel(\"x\")\n",
" plt.ylabel(\"z\")\n",
"\n",
" grid_x, grid_z = np.mgrid[pl_xmin:pl_xmax:200j, pl_zmin:pl_zmax:200j]\n",
" points = np.zeros((len(x), 2))\n",
" for i in range(len(x)):\n",
" # Zach says: No idea why x and y get flipped...\n",
" points[i][0] = x[i]\n",
" points[i][1] = z[i]\n",
"\n",
" grid = griddata(points, plotquantity, (grid_x, grid_z), method='nearest')\n",
" gridcub = griddata(points, plotquantity, (grid_x, grid_z), method='cubic')\n",
" im = plt.imshow(gridcub, extent=(pl_xmin,pl_xmax, pl_zmin,pl_zmax))\n",
" ax = plt.colorbar()\n",
" plt.clim(-3,3)\n",
" ax.set_label(plotdescription)\n",
" savefig(os.path.join(filename+\".png\"),dpi=150)\n",
" plt.close(fig)\n",
" sys.stdout.write(\"%c[2K\" % 27)\n",
" sys.stdout.write(\"Processing file \"+filename+\"\\r\")\n",
" sys.stdout.flush()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## Step 6.c: Generate visualization animation \\[Back to [top](#toc)\\]\n",
"$$\\label{genvideo}$$ \n",
"\n",
"In the following step, [ffmpeg](http://ffmpeg.org) is used to generate an [mp4](https://en.wikipedia.org/wiki/MPEG-4) video file, which can be played directly from this Jupyter notebook."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:40:06.722931Z",
"iopub.status.busy": "2021-06-15T11:40:06.722352Z",
"iopub.status.idle": "2021-06-15T11:40:07.599761Z",
"shell.execute_reply": "2021-06-15T11:40:07.599227Z"
}
},
"outputs": [],
"source": [
"## VISUALIZATION ANIMATION, PART 2: Combine PNGs to generate movie ##\n",
"\n",
"# https://stackoverflow.com/questions/14908576/how-to-remove-frame-from-matplotlib-pyplot-figure-vs-matplotlib-figure-frame\n",
"# https://stackoverflow.com/questions/23176161/animating-pngs-in-matplotlib-using-artistanimation\n",
"\n",
"fig = plt.figure(frameon=False)\n",
"ax = fig.add_axes([0, 0, 1, 1])\n",
"ax.axis('off')\n",
"\n",
"myimages = []\n",
"\n",
"for i in range(len(file_list)):\n",
" img = mgimg.imread(file_list[i]+\".png\")\n",
" imgplot = plt.imshow(img)\n",
" myimages.append([imgplot])\n",
"\n",
"ani = animation.ArtistAnimation(fig, myimages, interval=100, repeat_delay=1000)\n",
"plt.close()\n",
"ani.save(os.path.join(outdir,'Maxwell_ToroidalDipole.mp4'), fps=5,dpi=150)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:40:07.602767Z",
"iopub.status.busy": "2021-06-15T11:40:07.602243Z",
"iopub.status.idle": "2021-06-15T11:40:07.604288Z",
"shell.execute_reply": "2021-06-15T11:40:07.603832Z"
}
},
"outputs": [],
"source": [
"## VISUALIZATION ANIMATION, PART 3: Display movie as embedded HTML5 (see next cell) ##\n",
"\n",
"# https://stackoverflow.com/questions/18019477/how-can-i-play-a-local-video-in-my-ipython-notebook"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:40:07.607819Z",
"iopub.status.busy": "2021-06-15T11:40:07.607293Z",
"iopub.status.idle": "2021-06-15T11:40:07.609703Z",
"shell.execute_reply": "2021-06-15T11:40:07.609298Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n"
],
"text/plain": [
""
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Embed video based on suggestion:\n",
"# https://stackoverflow.com/questions/39900173/jupyter-notebook-html-cell-magic-with-python-variable\n",
"HTML(\"\"\"\n",
"\n",
"\"\"\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"# Step 7: Plot the numerical error, and confirm that it converges to zero with increasing numerical resolution (sampling) \\[Back to [top](#toc)\\]\n",
"$$\\label{convergence}$$"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"execution": {
"iopub.execute_input": "2021-06-15T11:40:07.780345Z",
"iopub.status.busy": "2021-06-15T11:40:07.614988Z",
"iopub.status.idle": "2021-06-15T11:40:08.394957Z",
"shell.execute_reply": "2021-06-15T11:40:08.394704Z"
}
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"