```
!nvidia-smi
```

    Sat Mar 13 00:02:05 2021
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 460.56       Driver Version: 460.32.03    CUDA Version: 11.2     |
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |                               |                      |               MIG M. |
    |===============================+======================+======================|
    |   0  Tesla T4            Off  | 00000000:00:04.0 Off |                    0 |
    | N/A   34C    P8     9W /  70W |      0MiB / 15109MiB |      0%      Default |
    |                               |                      |                  N/A |
    +-------------------------------+----------------------+----------------------+

    +-----------------------------------------------------------------------------+
    | Processes:                                                                  |
    |  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
    |        ID   ID                                                   Usage      |
    |=============================================================================|
    |  No running processes found                                                 |
    +-----------------------------------------------------------------------------+

```
!pip install pymatgen==2020.12.31
!pip install --pre graphdot
!pip install gdown

```

    Collecting pymatgen==2020.12.31
      Downloading https://files.pythonhosted.org/packages/e1/18/274b40cff34257a728071199d21105ced3116b42dd60793113eee7b1b5ca/pymatgen-2020.12.31.tar.gz (2.8MB)
         |████████████████████████████████| 2.8MB 14.3MB/s
    Requirement already satisfied: numpy>=1.14.3 in /usr/local/lib/python3.7/dist-packages (from pymatgen==2020.12.31) (1.19.5)
    Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from pymatgen==2020.12.31) (2.23.0)
    Collecting ruamel.yaml>=0.15.6
      Downloading https://files.pythonhosted.org/packages/ed/c3/4c823dac2949a6baf36a4987d04c50d30184147393ba6f4bfb4c67d15a13/ruamel.yaml-0.16.13-py2.py3-none-any.whl (111kB)
         |████████████████████████████████| 112kB 51.9MB/s
    Collecting monty>=3.0.2
      Downloading https://files.pythonhosted.org/packages/41/47/e6f045cd69f24df0b4ddd55fab329c079b7c9ce978a32431dce904f6a1d6/monty-2021.3.3-py3-none-any.whl (63kB)
         |████████████████████████████████| 71kB 10.3MB/s
    Collecting scipy>=1.5.0
      Downloading https://files.pythonhosted.org/packages/b6/3a/9e0649ab2d5ade703baa70ef980aa08739226e5d6a642f084bb201a92fc2/scipy-1.6.1-cp37-cp37m-manylinux1_x86_64.whl (27.4MB)
         |████████████████████████████████| 27.4MB 111kB/s
    Requirement already satisfied: tabulate in /usr/local/lib/python3.7/dist-packages (from pymatgen==2020.12.31) (0.8.9)
    Collecting spglib>=1.9.9.44
      Downloading https://files.pythonhosted.org/packages/4b/98/fa4760b9c71e2eace5a60b85dbf36dece49c379f8291cf1203056f287766/spglib-1.16.1-cp37-cp37m-manylinux2010_x86_64.whl (296kB)
         |████████████████████████████████| 296kB 49.5MB/s
    Requirement already satisfied: networkx>=2.2 in /usr/local/lib/python3.7/dist-packages (from pymatgen==2020.12.31) (2.5)
    Requirement already satisfied: matplotlib>=1.5 in /usr/local/lib/python3.7/dist-packages (from pymatgen==2020.12.31) (3.2.2)
    Requirement already satisfied: palettable>=3.1.1 in /usr/local/lib/python3.7/dist-packages (from pymatgen==2020.12.31) (3.3.0)
    Requirement already satisfied: sympy in /usr/local/lib/python3.7/dist-packages (from pymatgen==2020.12.31) (1.7.1)
    Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from pymatgen==2020.12.31) (1.1.5)
    Collecting plotly>=4.5.0
      Downloading https://files.pythonhosted.org/packages/1f/f6/bd3c17c8003b6641df1228e80e1acac97ed8402635e46c2571f8e1ef63af/plotly-4.14.3-py2.py3-none-any.whl (13.2MB)
         |████████████████████████████████| 13.2MB 252kB/s
    Collecting uncertainties>=3.1.4
      Downloading https://files.pythonhosted.org/packages/45/41/fc7e7b73b603e7c2c9e040b7aa8caf4a88d74b6faa567601ed82b6f0d8e1/uncertainties-3.1.5-py2.py3-none-any.whl (246kB)
         |████████████████████████████████| 256kB 53.5MB/s
    Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->pymatgen==2020.12.31) (3.0.4)
    Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->pymatgen==2020.12.31) (1.24.3)
    Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->pymatgen==2020.12.31) (2.10)
    Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->pymatgen==2020.12.31) (2020.12.5)
    Collecting ruamel.yaml.clib>=0.1.2; platform_python_implementation == "CPython" and python_version < "3.10"
      Downloading https://files.pythonhosted.org/packages/5e/6e/f652c56bbb2c3d3fca252ffc7c0358597f57a1bbdf484dac683054950c63/ruamel.yaml.clib-0.2.2-cp37-cp37m-manylinux1_x86_64.whl (547kB)
         |████████████████████████████████| 552kB 50.4MB/s
    Requirement already satisfied: decorator>=4.3.0 in /usr/local/lib/python3.7/dist-packages (from networkx>=2.2->pymatgen==2020.12.31) (4.4.2)
    Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=1.5->pymatgen==2020.12.31) (0.10.0)
    Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=1.5->pymatgen==2020.12.31) (2.8.1)
    Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=1.5->pymatgen==2020.12.31) (1.3.1)
    Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=1.5->pymatgen==2020.12.31) (2.4.7)
    Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.7/dist-packages (from sympy->pymatgen==2020.12.31) (1.2.1)
    Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.7/dist-packages (from pandas->pymatgen==2020.12.31) (2018.9)
    Requirement already satisfied: retrying>=1.3.3 in /usr/local/lib/python3.7/dist-packages (from plotly>=4.5.0->pymatgen==2020.12.31) (1.3.3)
    Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from plotly>=4.5.0->pymatgen==2020.12.31) (1.15.0)
    Requirement already satisfied: future in /usr/local/lib/python3.7/dist-packages (from uncertainties>=3.1.4->pymatgen==2020.12.31) (0.16.0)
    Building wheels for collected packages: pymatgen
      Building wheel for pymatgen (setup.py) ... done
      Created wheel for pymatgen: filename=pymatgen-2020.12.31-cp37-cp37m-linux_x86_64.whl size=3590921 sha256=fa2718dae94dee414021e253578fc4e052b71fa7fe2b7288e0c7adce3c6bbbac
      Stored in directory: /root/.cache/pip/wheels/bd/fd/4c/bbea735ca0989c51e67a45d1384b1ce3481bc2aa1337b4a6e9
    Successfully built pymatgen
    ERROR: albumentations 0.1.12 has requirement imgaug<0.2.7,>=0.2.5, but you'll have imgaug 0.2.9 which is incompatible.
    Installing collected packages: ruamel.yaml.clib, ruamel.yaml, monty, scipy, spglib, plotly, uncertainties, pymatgen
      Found existing installation: scipy 1.4.1
        Uninstalling scipy-1.4.1:
          Successfully uninstalled scipy-1.4.1
      Found existing installation: plotly 4.4.1
        Uninstalling plotly-4.4.1:
          Successfully uninstalled plotly-4.4.1
    Successfully installed monty-2021.3.3 plotly-4.14.3 pymatgen-2020.12.31 ruamel.yaml-0.16.13 ruamel.yaml.clib-0.2.2 scipy-1.6.1 spglib-1.16.1 uncertainties-3.1.5
    Collecting graphdot
      Downloading https://files.pythonhosted.org/packages/c5/3f/2b8521853057f5b8ffd7e8a56b9f6e4a7805f5fac4491561e26475f369b9/graphdot-0.8a16.tar.gz (103kB)
         |████████████████████████████████| 112kB 19.4MB/s
    Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.7/dist-packages (from graphdot) (1.19.5)
    Requirement already satisfied: scipy>=1.3.0 in /usr/local/lib/python3.7/dist-packages (from graphdot) (1.6.1)
    Requirement already satisfied: sympy>=1.3 in /usr/local/lib/python3.7/dist-packages (from graphdot) (1.7.1)
    Requirement already satisfied: pandas>=0.24 in /usr/local/lib/python3.7/dist-packages (from graphdot) (1.1.5)
    Requirement already satisfied: networkx>=2.4 in /usr/local/lib/python3.7/dist-packages (from graphdot) (2.5)
    Collecting pycuda>=2019
      Downloading https://files.pythonhosted.org/packages/46/61/47d3235a4c13eec5a5f03594ddb268f4858734e02980afbcd806e6242fa5/pycuda-2020.1.tar.gz (1.6MB)
         |████████████████████████████████| 1.6MB 37.0MB/s
    Collecting treelib>=1.6.1
      Downloading https://files.pythonhosted.org/packages/04/b0/2269c328abffbb63979f7143351a24a066776b87526d79956aea5018b80a/treelib-1.6.1.tar.gz
    Collecting kahypar>=1.1.4
      Downloading https://files.pythonhosted.org/packages/d2/c6/4b6ff807f2136079e9bc7289a793544541de4a04b402c678524647d6b0cb/kahypar-1.1.6-cp37-cp37m-manylinux2014_x86_64.whl (1.1MB)
         |████████████████████████████████| 1.1MB 39.9MB/s
    Requirement already satisfied: numba>=0.51.0 in /usr/local/lib/python3.7/dist-packages (from graphdot) (0.51.2)
    Collecting ase>=3.17
      Downloading https://files.pythonhosted.org/packages/a5/36/de17e79f29e06d9a92746d0dd9ec4636487ab03f6af10e78586aae533f7a/ase-3.21.1-py3-none-any.whl (2.2MB)
         |████████████████████████████████| 2.2MB 47.7MB/s
    Collecting pymatgen==2019.11.11
      Downloading https://files.pythonhosted.org/packages/57/f8/1d5f9bacde237107f917a5ca31bdf73e55a774ffb8e7b9e5f9cd7d7cf114/pymatgen-2019.11.11.tar.gz (2.5MB)
         |████████████████████████████████| 2.5MB 43.4MB/s
    Collecting mendeleev
      Downloading https://files.pythonhosted.org/packages/f0/75/5863bb298aa1390cb9ecb0548a62b8213ef085273f9d3c73e513b9c36214/mendeleev-0.6.1.tar.gz (193kB)
         |████████████████████████████████| 194kB 54.6MB/s
    Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.7/dist-packages (from sympy>=1.3->graphdot) (1.2.1)
    Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.24->graphdot) (2018.9)
    Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.24->graphdot) (2.8.1)
    Requirement already satisfied: decorator>=4.3.0 in /usr/local/lib/python3.7/dist-packages (from networkx>=2.4->graphdot) (4.4.2)
    Collecting pytools>=2011.2
      Downloading https://files.pythonhosted.org/packages/fb/fc/9628f0d2ec698360f4475bea0a88cb767b935f5347e6687bae0ffa342aab/pytools-2021.2.tar.gz (65kB)
         |████████████████████████████████| 71kB 9.7MB/s
    Requirement already satisfied: appdirs>=1.4.0 in /usr/local/lib/python3.7/dist-packages (from pycuda>=2019->graphdot) (1.4.4)
    Collecting mako
      Downloading https://files.pythonhosted.org/packages/f3/54/dbc07fbb20865d3b78fdb7cf7fa713e2cba4f87f71100074ef2dc9f9d1f7/Mako-1.1.4-py2.py3-none-any.whl (75kB)
         |████████████████████████████████| 81kB 11.0MB/s
    Requirement already satisfied: future in /usr/local/lib/python3.7/dist-packages (from treelib>=1.6.1->graphdot) (0.16.0)
    Requirement already satisfied: llvmlite<0.35,>=0.34.0.dev0 in /usr/local/lib/python3.7/dist-packages (from numba>=0.51.0->graphdot) (0.34.0)
    Requirement already satisfied: setuptools in /usr/local/lib/python3.7/dist-packages (from numba>=0.51.0->graphdot) (54.0.0)
    Requirement already satisfied: matplotlib>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from ase>=3.17->graphdot) (3.2.2)
    Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from pymatgen==2019.11.11->graphdot) (2.23.0)
    Requirement already satisfied: ruamel.yaml>=0.15.6 in /usr/local/lib/python3.7/dist-packages (from pymatgen==2019.11.11->graphdot) (0.16.13)
    Requirement already satisfied: monty>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from pymatgen==2019.11.11->graphdot) (2021.3.3)
    Collecting pydispatcher>=2.0.5
      Downloading https://files.pythonhosted.org/packages/cd/37/39aca520918ce1935bea9c356bcbb7ed7e52ad4e31bff9b943dfc8e7115b/PyDispatcher-2.0.5.tar.gz
    Requirement already satisfied: tabulate in /usr/local/lib/python3.7/dist-packages (from pymatgen==2019.11.11->graphdot) (0.8.9)
    Requirement already satisfied: spglib>=1.9.9.44 in /usr/local/lib/python3.7/dist-packages (from pymatgen==2019.11.11->graphdot) (1.16.1)
    Requirement already satisfied: palettable>=3.1.1 in /usr/local/lib/python3.7/dist-packages (from pymatgen==2019.11.11->graphdot) (3.3.0)
    Requirement already satisfied: sqlalchemy>=1.3.0 in /usr/local/lib/python3.7/dist-packages (from mendeleev->graphdot) (1.3.23)
    Collecting colorama
      Downloading https://files.pythonhosted.org/packages/44/98/5b86278fbbf250d239ae0ecb724f8572af1c91f4a11edf4d36a206189440/colorama-0.4.4-py2.py3-none-any.whl
    Collecting pyfiglet
      Downloading https://files.pythonhosted.org/packages/33/07/fcfdd7a2872f5b348953de35acce1544dab0c1e8368dca54279b1cde5c15/pyfiglet-0.8.post1-py2.py3-none-any.whl (865kB)
         |████████████████████████████████| 870kB 45.5MB/s
    Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas>=0.24->graphdot) (1.15.0)
    Requirement already satisfied: MarkupSafe>=0.9.2 in /usr/local/lib/python3.7/dist-packages (from mako->pycuda>=2019->graphdot) (1.1.1)
    Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=2.0.0->ase>=3.17->graphdot) (1.3.1)
    Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=2.0.0->ase>=3.17->graphdot) (0.10.0)
    Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=2.0.0->ase>=3.17->graphdot) (2.4.7)
    Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->pymatgen==2019.11.11->graphdot) (3.0.4)
    Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->pymatgen==2019.11.11->graphdot) (2020.12.5)
    Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->pymatgen==2019.11.11->graphdot) (1.24.3)
    Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->pymatgen==2019.11.11->graphdot) (2.10)
    Requirement already satisfied: ruamel.yaml.clib>=0.1.2; platform_python_implementation == "CPython" and python_version < "3.10" in /usr/local/lib/python3.7/dist-packages (from ruamel.yaml>=0.15.6->pymatgen==2019.11.11->graphdot) (0.2.2)
    Building wheels for collected packages: graphdot, pycuda, treelib, pymatgen, mendeleev, pytools, pydispatcher
      Building wheel for graphdot (setup.py) ... done
      Created wheel for graphdot: filename=graphdot-0.8a16-cp37-none-any.whl size=148200 sha256=c779dc3799fdf9a5a09f4c20619ef195d03192873e67c84c0f47fa6a08ff7277
      Stored in directory: /root/.cache/pip/wheels/e6/0d/f0/8edb618420134169eceece7cb4c1f071f9ea6e84385383310b
      Building wheel for pycuda (setup.py) ... done
      Created wheel for pycuda: filename=pycuda-2020.1-cp37-cp37m-linux_x86_64.whl size=621092 sha256=7df4961826788892cfcc89433882633b1b6c3f76e3fbcb3541c2d3303d209059
      Stored in directory: /root/.cache/pip/wheels/8f/78/d1/5bb826f81d9d490297a348d818ff3ee6dd6f2075b06dde6ea0
      Building wheel for treelib (setup.py) ... done
      Created wheel for treelib: filename=treelib-1.6.1-cp37-none-any.whl size=18370 sha256=6d8beb53754f9d3c4e88c1316d9d35c15dbce1d6996398127f10fa867db39c90
      Stored in directory: /root/.cache/pip/wheels/68/1d/92/c50ec52951ccebafb40f3b8f0beb28fbaf745431c14a17c497
      Building wheel for pymatgen (setup.py) ... done
      Created wheel for pymatgen: filename=pymatgen-2019.11.11-cp37-cp37m-linux_x86_64.whl size=3324718 sha256=387ba9130806a420a65a0eeab5219c0dd55fa8406fa8ca85eea3c2abc95a0e3d
      Stored in directory: /root/.cache/pip/wheels/98/23/3c/3b929997e5f8976361933411e8a3b9bdf1b2702e7830e7a7ad
      Building wheel for mendeleev (setup.py) ... done
      Created wheel for mendeleev: filename=mendeleev-0.6.1-py2.py3-none-any.whl size=174964 sha256=bd558acea44caa80addf69f0165c7e3c6408cc85d92c1bf04c17e6248c3d87b3
      Stored in directory: /root/.cache/pip/wheels/fb/28/5d/95e69a718b35dd00169889b0139a692f6c265d399cab3aa097
      Building wheel for pytools (setup.py) ... done
      Created wheel for pytools: filename=pytools-2021.2-py2.py3-none-any.whl size=62446 sha256=a8d8944ef3da8121e31191e9ae48eee46ebb8aa6218d944e27e8e32017777f7a
      Stored in directory: /root/.cache/pip/wheels/d3/13/e8/fcb236c8cb91fb549a37f1d86783af99f0e0bcbeb9568ee5e2
      Building wheel for pydispatcher (setup.py) ... done
      Created wheel for pydispatcher: filename=PyDispatcher-2.0.5-cp37-none-any.whl size=11517 sha256=2ae5b088af67f209f3cb85511b60ad04bcf38515c81d3884293bf7cc722159b0
      Stored in directory: /root/.cache/pip/wheels/88/99/96/cfef6665f9cb1522ee6757ae5955feedf2fe25f1737f91fa7f
    Successfully built graphdot pycuda treelib pymatgen mendeleev pytools pydispatcher
    Installing collected packages: pytools, mako, pycuda, treelib, kahypar, ase, pydispatcher, pymatgen, colorama, pyfiglet, mendeleev, graphdot
      Found existing installation: pymatgen 2020.12.31
        Uninstalling pymatgen-2020.12.31:
          Successfully uninstalled pymatgen-2020.12.31
    Successfully installed ase-3.21.1 colorama-0.4.4 graphdot-0.8a16 kahypar-1.1.6 mako-1.1.4 mendeleev-0.6.1 pycuda-2020.1 pydispatcher-2.0.5 pyfiglet-0.8.post1 pymatgen-2019.11.11 pytools-2021.2 treelib-1.6.1
    Requirement already satisfied: gdown in /usr/local/lib/python3.7/dist-packages (3.6.4)
    Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from gdown) (2.23.0)
    Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from gdown) (1.15.0)
    Requirement already satisfied: tqdm in /usr/local/lib/python3.7/dist-packages (from gdown) (4.41.1)
    Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->gdown) (2.10)
    Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->gdown) (3.0.4)
    Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->gdown) (2020.12.5)
    Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->gdown) (1.24.3)

```
%matplotlib inline
import io
import sys
sys.path.append('/usr/local/lib/python3.6/site-packages/')
import os
import urllib
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import graphdot
from graphdot import Graph
from graphdot.graph.adjacency import AtomicAdjacency
from graphdot.graph.reorder import rcm
from graphdot.kernel.marginalized import MarginalizedGraphKernel
from graphdot.kernel.marginalized.starting_probability import Uniform
from graphdot.model.gaussian_process import (
    GaussianProcessRegressor,
    LowRankApproximateGPR
)
from graphdot.kernel.fix import Normalization
import graphdot.microkernel as uX
import ase.io
```

    /usr/local/lib/python3.7/dist-packages/graphdot/graph/__init__.py:24: UserWarning: Cannot import RDKit, `graph.from_rdkit()` will be unavailable.

      'Cannot import RDKit, `graph.from_rdkit()` will be unavailable.\n'

```
from google.colab import drive
drive.mount('/content/gdrive')
```

    Mounted at /content/gdrive

```
cd gdrive/MyDrive/Google\ Colab/Covid-Data
```

    /content/gdrive/MyDrive/Google Colab/Covid-Data

```
files  = ['uncharged_NSP15_6W01_A_3_H.Orderable_zinc_db_enaHLL.2col.csv.1.xz']
dataset = pd.read_pickle(files[0])
#frames = [pd.read_pickle(f) for f in files]
#dataset = pd.concat(frames)
```

```
dataset.head(5)
```

      energy
      smiles
      graphs

      0
      -2.265697
      Cc1nc(no1)c2cncnc2[C@@H]3CCCN(C3)C(=O)Cc4ccccc4
      Graph(nodes={'!i': [ 0, 1, 2, 3, 4, 5, 6, 7, 8...

      1
      -2.351519
      Cc1ccc(cc1)c2nnc(n2N)SCC(=O)Nc3ccccc3OC
      Graph(nodes={'!i': [ 0, 1, 2, 3, 4, 5, 6, 7, 8...

      2
      -3.308996
      CCOC(=O)Cn1c2ccccc2nc1[C@H]3CC(=O)N(C3)c4ccc(c...
      Graph(nodes={'!i': [ 0, 1, 2, 3, 4, 5, 6, 7, 8...

      3
      -3.760179
      CC[C@H](C)NC(=O)[C@@H](CC)N(Cc1ccccc1)C(=O)Cc2...
      Graph(nodes={'!i': [ 0, 1, 2, 3, 4, 5, 6, 7, 8...

      4
      -2.895577
      Cc1cccc2c1ccn2CCC(=O)N3CCc4cc(c(cc4C3)OC)OC
      Graph(nodes={'!i': [ 0, 1, 2, 3, 4, 5, 6, 7, 8...

```
target = 'energy'
N_train = 2500
N_test = 5000
```

```
np.random.seed(0)
train_sel = np.random.choice(len(dataset), N_train, replace=False)
test_sel = np.random.choice(np.setxor1d(np.arange(len(dataset)), train_sel), N_test, replace=False)
train = dataset.iloc[train_sel]
test = dataset.iloc[test_sel]
```

```
gpr = GaussianProcessRegressor(
    kernel=Normalization(
        MarginalizedGraphKernel(
            node_kernel=uX.Additive(
                aromatic=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.5,(0.1, 0.9)),
                atomic_number=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.8,(0.1, 0.9)),
                charge=uX.Constant(0.5, (0.01, 10.0)) * uX.SquareExponential(1.0),
                chiral=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.5,(0.1, 0.9)),
                hcount=uX.Constant(0.5, (0.01, 10.0)) * uX.SquareExponential(1.0),
                hybridization=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.5,(0.1, 0.9)),
                ring_list=uX.Constant(0.5, (0.01, 100.0)) * uX.Convolution(uX.KroneckerDelta(0.5,(0.1, 0.9)))
            ).normalized,
            edge_kernel=uX.Additive(
                aromatic=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.5,(0.1, 0.9)),
                conjugated=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.5,(0.1, 0.9)),
                order=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.8,(0.1, 0.9)),
                ring_stereo=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.8,(0.1, 0.9)),
                stereo=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.8,(0.1, 0.9))
            ).normalized,
            p=Uniform(1.0, p_bounds='fixed'),
            q=0.05
        )
    ),
    alpha=1e-4,
    optimizer=True,
    normalize_y=True,
    regularization='+',
)
```

```
gpr.fit(train.graphs, train[target], repeat=3, verbose=True)
```

    |        logP|       dlogP|     y^T.K.y|     log|K| |     Cond(K)|  GPU time|  CPU time|
    |------------|------------|------------|------------|------------|----------|----------|
    |  9.2483e+06|  5.6205e+07|  9.2681e+06|      -19798|  2.2708e+07|   1.3e+02|         2|
    |  7.0477e+06|  5.4659e+07|  7.0664e+06|      -18684|  2.1871e+07|   1.3e+02|       1.8|
    |  4.8851e+06|  4.7042e+07|  4.9024e+06|      -17313|  2.0436e+07|   1.2e+02|       1.9|
    |  4.1663e+06|  4.0942e+07|  4.1831e+06|      -16749|  1.9691e+07|   1.2e+02|       3.1|
    |  3.6447e+06|  3.5014e+07|  3.6609e+06|      -16275|  1.8951e+07|   1.2e+02|       3.2|
    |  3.3263e+06|  3.0755e+07|  3.3423e+06|      -15945|  1.8326e+07|   1.1e+02|       3.4|
    |  3.1808e+06|  2.8965e+07|  3.1966e+06|      -15788|  1.8127e+07|   1.1e+02|       3.5|
    |  3.1636e+06|  2.8096e+07|  3.1793e+06|      -15754|  1.7693e+07|   1.1e+02|       3.5|
    |  3.1148e+06|  2.8068e+07|  3.1305e+06|      -15707|  1.7766e+07|   1.1e+02|       3.5|
    |  3.1039e+06|  2.7961e+07|  3.1196e+06|      -15698|  1.7887e+07|   1.1e+02|       3.6|
    |  3.0983e+06|  2.7874e+07|   3.114e+06|      -15692|  1.7891e+07|   1.1e+02|       3.7|
    |  3.0871e+06|   2.787e+07|  3.1028e+06|      -15680|  1.7867e+07|   1.1e+02|       3.8|
    |  3.0815e+06|  2.7741e+07|  3.0971e+06|      -15675|  1.7885e+07|   1.1e+02|       3.9|
    |  3.0762e+06|  2.7713e+07|  3.0918e+06|      -15673|  1.7843e+07|   1.1e+02|         4|
    |  3.0733e+06|  2.7745e+07|   3.089e+06|      -15672|  1.7842e+07|   1.1e+02|         2|
    |  3.0743e+06|  2.7867e+07|    3.09e+06|      -15672|   1.784e+07|   1.1e+02|         2|
    |  3.0747e+06|  2.7782e+07|  3.0904e+06|      -15672|  1.7844e+07|   1.1e+02|       1.9|
    |  3.0748e+06|  2.7762e+07|  3.0904e+06|      -15672|  1.7849e+07|   1.1e+02|       1.9|
    |   3.073e+06|  2.7737e+07|  3.0887e+06|      -15672|  1.7842e+07|   1.1e+02|       1.9|
    |  3.0737e+06|   2.775e+07|  3.0893e+06|      -15672|   1.783e+07|   1.1e+02|       1.9|
    |  3.0723e+06|  2.7726e+07|   3.088e+06|      -15672|  1.7824e+07|   1.1e+02|       1.9|
    |   3.075e+06|  2.7889e+07|  3.0906e+06|      -15673|  1.7805e+07|   1.1e+02|       1.9|
    |   3.075e+06|  2.7778e+07|  3.0907e+06|      -15672|  1.7836e+07|   1.1e+02|         2|
    |  3.0736e+06|  2.7744e+07|  3.0893e+06|      -15672|  1.7848e+07|   1.1e+02|       1.9|
    |  3.0738e+06|  2.7755e+07|  3.0895e+06|      -15672|  1.7836e+07|   1.1e+02|       1.9|
    |  3.0723e+06|  2.7726e+07|  3.0879e+06|      -15672|  1.7843e+07|   1.1e+02|         2|
    |  3.0729e+06|  2.7733e+07|  3.0886e+06|      -15672|  1.7837e+07|   1.1e+02|       1.9|
    |  3.0737e+06|  2.7751e+07|  3.0894e+06|      -15672|  1.7844e+07|   1.1e+02|         2|
    |  3.0728e+06|  2.7731e+07|  3.0885e+06|      -15672|  1.7845e+07|   1.1e+02|         2|
    |        logP|       dlogP|     y^T.K.y|     log|K| |     Cond(K)|  GPU time|  CPU time|
    |------------|------------|------------|------------|------------|----------|----------|
    |  9.7674e+06|   7.105e+07|  9.7874e+06|      -19989|  2.2325e+07|   1.6e+02|         2|
    |  7.4121e+06|  6.7322e+07|   7.431e+06|      -18879|  2.1812e+07|   1.5e+02|       1.9|
    |  5.4618e+06|  5.7277e+07|  5.4796e+06|      -17744|  2.0827e+07|   1.4e+02|       1.9|
    |  4.6314e+06|  4.9361e+07|  4.6486e+06|      -17148|  2.0213e+07|   1.3e+02|         2|
    |  4.1207e+06|  4.3868e+07|  4.1375e+06|      -16726|  1.9615e+07|   1.3e+02|         2|
    |  3.6953e+06|  3.8578e+07|  3.7116e+06|      -16337|  1.9095e+07|   1.2e+02|       2.1|
    |  3.4328e+06|  3.4685e+07|  3.4489e+06|      -16076|  1.8614e+07|   1.2e+02|         2|
    |  3.2487e+06|  2.9831e+07|  3.2645e+06|      -15864|  1.8236e+07|   1.1e+02|         2|
    |  3.1564e+06|  2.9162e+07|  3.1721e+06|      -15769|  1.8106e+07|   1.1e+02|         2|
    |  3.1359e+06|  2.8967e+07|  3.1516e+06|      -15744|  1.7972e+07|   1.1e+02|         2|
    |  3.1081e+06|  2.8518e+07|  3.1239e+06|      -15713|  1.7922e+07|   1.1e+02|         2|
    |  3.0969e+06|  2.8242e+07|  3.1126e+06|      -15698|  1.7902e+07|   1.1e+02|         2|
    |  3.0828e+06|  2.7696e+07|  3.0985e+06|      -15682|  1.7926e+07|   1.1e+02|         2|
    |  3.0814e+06|  2.7725e+07|  3.0971e+06|      -15679|  1.7879e+07|   1.1e+02|         2|
    |  3.0786e+06|  2.7724e+07|  3.0943e+06|      -15678|  1.7854e+07|   1.1e+02|         2|
    |  3.0788e+06|  2.7803e+07|  3.0945e+06|      -15676|  1.7835e+07|   1.1e+02|         2|
    |  3.0793e+06|  2.7747e+07|   3.095e+06|      -15678|  1.7856e+07|   1.1e+02|         2|
    |  3.0798e+06|  2.7753e+07|  3.0954e+06|      -15678|  1.7841e+07|   1.1e+02|       2.1|
    |  3.0812e+06|  2.7766e+07|  3.0968e+06|      -15678|  1.7836e+07|   1.1e+02|         2|
    |  3.0791e+06|  2.7736e+07|  3.0948e+06|      -15678|  1.7868e+07|   1.1e+02|         2|
    |  3.0789e+06|   2.773e+07|  3.0946e+06|      -15678|  1.7852e+07|   1.1e+02|         2|
    |        logP|       dlogP|     y^T.K.y|     log|K| |     Cond(K)|  GPU time|  CPU time|
    |------------|------------|------------|------------|------------|----------|----------|
    |  1.3416e+07|  2.7823e+07|  1.3437e+07|      -21350|  2.3927e+07|   1.1e+02|         2|
    |  1.1311e+07|  3.7692e+07|  1.1332e+07|      -20625|   2.321e+07|   1.2e+02|       1.9|
    |  5.3701e+06|  4.4484e+07|  5.3878e+06|      -17634|  2.0953e+07|   1.2e+02|       1.9|
    |  3.7039e+06|  3.3779e+07|  3.7202e+06|      -16298|  1.8805e+07|   1.2e+02|       1.9|
    |  3.4237e+06|  3.0303e+07|  3.4397e+06|      -16027|  1.8516e+07|   1.1e+02|       1.9|
    |  3.2623e+06|   2.902e+07|  3.2782e+06|      -15866|  1.8245e+07|   1.1e+02|         2|
    |  3.1641e+06|  2.8458e+07|  3.1799e+06|      -15761|   1.793e+07|   1.1e+02|       1.9|
    |  3.1255e+06|   2.815e+07|  3.1412e+06|      -15720|  1.7994e+07|   1.1e+02|       1.9|
    |  3.0972e+06|  2.7847e+07|  3.1129e+06|      -15686|  1.7824e+07|   1.1e+02|         2|
    |  3.0941e+06|   2.779e+07|  3.1098e+06|      -15681|  1.7811e+07|   1.1e+02|       1.9|
    |  3.0908e+06|   2.788e+07|  3.1065e+06|      -15678|  1.7836e+07|   1.1e+02|         2|
    |  3.0893e+06|  2.7791e+07|  3.1049e+06|      -15677|  1.7835e+07|   1.1e+02|         2|
    |  3.0886e+06|  2.7739e+07|  3.1042e+06|      -15676|  1.7826e+07|   1.1e+02|         2|
    |  3.0864e+06|  2.7668e+07|  3.1021e+06|      -15675|  1.7838e+07|   1.1e+02|       1.9|
    |  3.0834e+06|  2.7706e+07|  3.0991e+06|      -15673|   1.786e+07|   1.1e+02|         2|
    |  3.0821e+06|  2.7687e+07|  3.0977e+06|      -15672|  1.7816e+07|   1.1e+02|       1.9|
    |  3.0821e+06|    2.77e+07|  3.0977e+06|      -15672|  1.7825e+07|   1.1e+02|         2|
    |  3.0817e+06|  2.7683e+07|  3.0974e+06|      -15672|  1.7826e+07|   1.1e+02|       1.9|
    |  3.0813e+06|  2.7732e+07|   3.097e+06|      -15672|  1.7815e+07|   1.1e+02|       1.9|
    |  3.0804e+06|  2.7898e+07|  3.0961e+06|      -15677|  1.7811e+07|   1.1e+02|         2|
    |  3.0775e+06|  2.7864e+07|  3.0932e+06|      -15675|  1.7796e+07|   1.1e+02|         2|
    |  3.0758e+06|  2.7888e+07|  3.0915e+06|      -15674|   1.785e+07|   1.1e+02|       1.9|
    |   3.075e+06|    2.79e+07|  3.0907e+06|      -15674|  1.7856e+07|   1.1e+02|       1.9|
    |  3.0745e+06|  2.7864e+07|  3.0901e+06|      -15674|  1.7843e+07|   1.1e+02|         2|
    |  3.0741e+06|  2.7849e+07|  3.0898e+06|      -15673|   1.784e+07|   1.1e+02|         2|
    |   3.075e+06|  2.7851e+07|  3.0907e+06|      -15672|  1.7851e+07|   1.1e+02|         2|
    |  3.0743e+06|  2.7844e+07|    3.09e+06|      -15673|  1.7834e+07|   1.1e+02|       1.9|
    |  3.0746e+06|  2.7848e+07|  3.0903e+06|      -15673|  1.7826e+07|   1.1e+02|         2|
    |   3.074e+06|  2.7841e+07|  3.0897e+06|      -15673|   1.786e+07|   1.1e+02|         2|
    |  3.0748e+06|  2.7863e+07|  3.0905e+06|      -15673|  1.7837e+07|   1.1e+02|       1.9|
    |  3.0748e+06|  2.7858e+07|  3.0904e+06|      -15673|  1.7846e+07|   1.1e+02|       1.9|
    Optimization result:
          fun: 3072837.549856819
     hess_inv: <25x25 LbfgsInvHessProduct with dtype=float64>
          jac: array([ 2.77173629e+03,  8.63091068e+02,  2.24459039e+02, -5.40556268e+03,
            5.34039129e+04,  1.09446494e+03,  0.00000000e+00, -2.01899144e+03,
            1.10823575e+03,  8.21839298e+03,  7.60393519e-15,  6.05781870e+02,
            3.50613662e+02, -3.40939052e+03,  6.56884593e+04,  1.17076522e+03,
            7.37607748e+03, -1.54956743e+03,  1.06405848e+04, -1.05655723e+03,
            9.70572233e+02,  1.09689017e+03,  0.00000000e+00,  3.33513390e+02,
            1.31117462e+03])
      message: 'CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH'
         nfev: 29
          nit: 16
         njev: 29
       status: 0
      success: True
            x: array([-9.21034037, -3.87543474, -1.69111274,  1.66992633, -2.30258509,
           -4.40365014,  0.        , -2.5704035 , -2.1973491 ,  2.29742905,
           -2.30904354, -3.62985763, -1.79849954,  1.88246002, -2.30258509,
            0.51066812, -2.30258509,  0.84382344, -2.30258509, -2.71750085,
           -1.57822743, -3.60981968, -0.22314355, -1.29211429, -2.22365827])

    <graphdot.model.gaussian_process.gpr.GaussianProcessRegressor at 0x7f27bb4d48d0>

```
gpr.kernel.hyperparameters
```

    starting_probability : Uniform
    	p : 1.0
    stopping_probability : 0.00010000000000000009
    node_kernel : Composite
    	aromatic : Multiply
    		lhs : Constant
    			c : 0.020745317040533336
    		rhs : KroneckerDelta
    			h : 0.18431431562315057
    	atomic_number : Multiply
    		lhs : Constant
    			c : 5.311776469014586
    		rhs : KroneckerDelta
    			h : 0.10000000000000002
    	charge : Multiply
    		lhs : Constant
    			c : 0.012232607607837629
    		rhs : SquareExponential
    			length_scale : 1.0
    	chiral : Multiply
    		lhs : Constant
    			c : 0.07650466922172743
    		rhs : KroneckerDelta
    			h : 0.11109727647636178
    	hcount : Multiply
    		lhs : Constant
    			c : 9.948572239474858
    		rhs : SquareExponential
    			length_scale : 0.09935623660147404
    	hybridization : Multiply
    		lhs : Constant
    			c : 0.026519959900936984
    		rhs : KroneckerDelta
    			h : 0.16554709935637946
    	ring_list : Multiply
    		lhs : Constant
    			c : 6.569646480637104
    		rhs : Convolution
    			base : KroneckerDelta
    				h : 0.10000000000000002
    edge_kernel : Composite
    	aromatic : Multiply
    		lhs : Constant
    			c : 1.6664041788716395
    		rhs : KroneckerDelta
    			h : 0.10000000000000002
    	conjugated : Multiply
    		lhs : Constant
    			c : 2.3252404085414984
    		rhs : KroneckerDelta
    			h : 0.10000000000000002
    	order : Multiply
    		lhs : Constant
    			c : 0.0660395912613341
    		rhs : KroneckerDelta
    			h : 0.20634052632087976
    	ring_stereo : Multiply
    		lhs : Constant
    			c : 0.02705672519567324
    		rhs : KroneckerDelta
    			h : 0.8
    	stereo : Multiply
    		lhs : Constant
    			c : 0.27468939675048937
    		rhs : KroneckerDelta
    			h : 0.10821251378092044

```
mu = gpr.predict(train.graphs)
```

```
plt.scatter(train[target], mu)
plt.show()
```

```
print('Training set')
print('MAE:', np.mean(np.abs(train[target] - mu)))
print('RMSE:', np.std(train[target] - mu))
```

    Training set
    MAE: 0.20686970935482746
    RMSE: 0.3186909692030075

```
mu_test = gpr.predict(test.graphs)
```

```
plt.scatter(test[target], mu_test)
plt.show()
```

```
print('Test set')
print('MAE:', np.mean(np.abs(test[target] - mu_test)))
print('RMSE:', np.std(test[target] - mu_test))
```

    MAE: 1.244993771620827
    RMSE: 1.6025986390757625

```
gpr2 = GaussianProcessRegressor(
    kernel=Normalization(
        MarginalizedGraphKernel(
            node_kernel=uX.Additive(
                aromatic=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.5,(0.1, 0.9)),
                atomic_number=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.8,(0.1, 0.9)),
                charge=uX.Constant(0.5, (0.01, 10.0)) * uX.SquareExponential(1.0),
                chiral=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.5,(0.1, 0.9)),
                hcount=uX.Constant(0.5, (0.01, 10.0)) * uX.SquareExponential(1.0),
                hybridization=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.5,(0.1, 0.9)),
                ring_list=uX.Constant(0.5, (0.01, 100.0)) * uX.Convolution(uX.KroneckerDelta(0.5,(0.1, 0.9)))
            ).normalized,
            edge_kernel=uX.Additive(
                aromatic=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.5,(0.1, 0.9)),
                conjugated=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.5,(0.1, 0.9)),
                order=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.8,(0.1, 0.9)),
                ring_stereo=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.8,(0.1, 0.9)),
                stereo=uX.Constant(0.5, (0.01, 10.0)) * uX.KroneckerDelta(0.8,(0.1, 0.9))
            ).normalized,
            p=Uniform(1.0, p_bounds='fixed'),
            q=0.05
        )
    ),
    alpha=1e-2,
    optimizer=True,
    normalize_y=True,
    regularization='+',
)
```

```
gpr2.fit(train.graphs, train[target], repeat=3, verbose=True)
```

    |        logP|       dlogP|     y^T.K.y|     log|K| |     Cond(K)|  GPU time|  CPU time|
    |------------|------------|------------|------------|------------|----------|----------|
    |   1.667e+05|  1.9282e+05|  1.7773e+05|      -11034|  2.2742e+05|   1.3e+02|       1.9|
    |  1.5585e+05|  2.2172e+05|  1.6671e+05|      -10857|  2.2218e+05|   1.3e+02|         2|
    |  1.3711e+05|  2.4873e+05|  1.4755e+05|      -10447|  2.0803e+05|   1.2e+02|         2|
    |  1.3286e+05|  2.3628e+05|   1.432e+05|      -10338|  2.0336e+05|   1.2e+02|       1.9|
    |  1.2977e+05|  2.2742e+05|  1.4002e+05|      -10249|  1.9714e+05|   1.1e+02|         2|
    |  1.3007e+05|  2.1427e+05|  1.4032e+05|      -10258|  2.0121e+05|   1.1e+02|       1.9|
    |  1.2923e+05|  2.2102e+05|  1.3946e+05|      -10238|  1.9906e+05|   1.1e+02|         2|
    |  1.2888e+05|  2.2097e+05|  1.3911e+05|      -10229|  1.9866e+05|   1.1e+02|       1.9|
    |  1.2843e+05|  2.2339e+05|  1.3864e+05|      -10211|  1.9581e+05|   1.1e+02|         2|
    |  1.2837e+05|  2.2244e+05|  1.3858e+05|      -10212|   1.969e+05|   1.1e+02|         2|
    |  1.2836e+05|  2.2224e+05|  1.3857e+05|      -10212|  1.9697e+05|   1.1e+02|         2|
    |  1.2832e+05|  2.2155e+05|  1.3853e+05|      -10211|  1.9716e+05|   1.1e+02|       1.9|
    |  1.2826e+05|  2.2184e+05|  1.3847e+05|      -10209|  1.9704e+05|   1.1e+02|       1.9|
    |  1.2821e+05|   2.218e+05|  1.3841e+05|      -10207|  1.9672e+05|   1.1e+02|       1.9|
    |  1.2819e+05|  2.2165e+05|   1.384e+05|      -10207|  1.9664e+05|   1.1e+02|       1.9|
    |  1.2818e+05|  2.2129e+05|  1.3839e+05|      -10207|  1.9671e+05|   1.1e+02|       1.9|
    |  1.2817e+05|  2.2108e+05|  1.3838e+05|      -10207|  1.9674e+05|   1.1e+02|         2|
    |  1.2815e+05|  2.2069e+05|  1.3836e+05|      -10207|  1.9678e+05|   1.1e+02|       1.9|
    |  1.2812e+05|  2.1806e+05|  1.3833e+05|      -10210|  1.9699e+05|   1.1e+02|       1.9|
    |   1.281e+05|  2.1842e+05|   1.383e+05|      -10208|  1.9697e+05|   1.1e+02|         2|
    |  1.2807e+05|  2.1757e+05|  1.3828e+05|      -10208|  1.9698e+05|   1.1e+02|       1.9|
    |  1.2806e+05|  2.1787e+05|  1.3827e+05|      -10208|  1.9678e+05|   1.1e+02|       1.9|
    |  1.2805e+05|  2.1731e+05|  1.3825e+05|      -10208|   1.969e+05|   1.1e+02|       1.9|
    |  1.2805e+05|  2.1704e+05|  1.3825e+05|      -10208|  1.9693e+05|   1.1e+02|       1.9|
    |  1.2805e+05|  2.1692e+05|  1.3825e+05|      -10208|  1.9695e+05|   1.1e+02|       1.9|
    |  1.2805e+05|  2.1703e+05|  1.3825e+05|      -10208|  1.9693e+05|   1.1e+02|       1.9|
    |  1.2804e+05|  2.1694e+05|  1.3825e+05|      -10208|  1.9694e+05|   1.1e+02|       1.8|
    |        logP|       dlogP|     y^T.K.y|     log|K| |     Cond(K)|  GPU time|  CPU time|
    |------------|------------|------------|------------|------------|----------|----------|
    |   1.598e+05|  2.3746e+05|  1.7074e+05|      -10939|  2.2637e+05|   1.4e+02|       1.9|
    |    1.51e+05|  2.4982e+05|  1.6178e+05|      -10778|  2.2182e+05|   1.3e+02|         2|
    |  1.3818e+05|  2.5682e+05|  1.4865e+05|      -10478|  2.1043e+05|   1.2e+02|       1.9|
    |  1.3264e+05|  2.3404e+05|  1.4297e+05|      -10329|  2.0251e+05|   1.1e+02|       1.9|
    |  1.3026e+05|  2.2465e+05|  1.4053e+05|      -10266|  2.0075e+05|   1.2e+02|       1.9|
    |  1.2905e+05|  2.2268e+05|  1.3928e+05|      -10231|    1.98e+05|   1.1e+02|       1.9|
    |  1.2875e+05|  2.2218e+05|  1.3898e+05|      -10222|   1.972e+05|   1.1e+02|       1.9|
    |  1.2846e+05|  2.2218e+05|  1.3867e+05|      -10215|  1.9746e+05|   1.1e+02|       1.9|
    |  1.2842e+05|  2.2237e+05|  1.3863e+05|      -10213|    1.97e+05|   1.1e+02|       1.9|
    |  1.2839e+05|   2.223e+05|   1.386e+05|      -10212|  1.9683e+05|   1.1e+02|       1.9|
    |  1.2834e+05|   2.221e+05|  1.3855e+05|      -10211|  1.9661e+05|   1.1e+02|       1.9|
    |  1.2827e+05|  2.2204e+05|  1.3848e+05|      -10209|  1.9656e+05|   1.1e+02|       1.9|
    |  1.2847e+05|  2.1854e+05|  1.3869e+05|      -10219|  1.9944e+05|   1.1e+02|         2|
    |  1.2825e+05|  2.2117e+05|  1.3846e+05|      -10209|  1.9725e+05|   1.1e+02|       1.9|
    |  1.2818e+05|  2.2112e+05|  1.3839e+05|      -10207|  1.9694e+05|   1.1e+02|       1.9|
    |  1.2815e+05|  2.2103e+05|  1.3836e+05|      -10207|  1.9673e+05|   1.1e+02|       1.9|
    |  1.2809e+05|   2.199e+05|   1.383e+05|      -10206|  1.9649e+05|   1.1e+02|       1.9|
    |  1.2859e+05|  2.0873e+05|  1.3881e+05|      -10225|  1.9638e+05|   1.1e+02|       1.9|
    |  1.2806e+05|  2.1858e+05|  1.3827e+05|      -10207|  1.9647e+05|   1.1e+02|       1.9|
    |  1.2805e+05|  2.1677e+05|  1.3826e+05|      -10207|  1.9652e+05|   1.1e+02|       1.8|
    |  1.2805e+05|  2.1694e+05|  1.3826e+05|      -10207|   1.967e+05|   1.1e+02|       1.9|
    |  1.2805e+05|   2.167e+05|  1.3825e+05|      -10207|  1.9688e+05|   1.1e+02|       1.9|
    |  1.2805e+05|  2.1664e+05|  1.3825e+05|      -10207|  1.9691e+05|   1.1e+02|       1.9|
    |        logP|       dlogP|     y^T.K.y|     log|K| |     Cond(K)|  GPU time|  CPU time|
    |------------|------------|------------|------------|------------|----------|----------|
    |  1.6725e+05|  1.9567e+05|  1.7829e+05|      -11040|  2.2401e+05|   1.4e+02|       1.9|
    |  1.5632e+05|  2.2001e+05|  1.6717e+05|      -10858|  2.2063e+05|   1.3e+02|       1.9|
    |  1.4534e+05|  2.4266e+05|  1.5597e+05|      -10631|  2.1449e+05|   1.2e+02|       1.9|
    |  1.3481e+05|  2.3484e+05|  1.4519e+05|      -10385|  2.0372e+05|   1.2e+02|       1.9|
    |  1.3073e+05|  2.2726e+05|  1.4102e+05|      -10288|  2.0201e+05|   1.2e+02|       1.9|
    |  1.2984e+05|  2.1929e+05|  1.4009e+05|      -10254|   1.992e+05|   1.1e+02|       1.9|
    |  1.2914e+05|  2.2195e+05|  1.3938e+05|      -10239|  1.9863e+05|   1.1e+02|       1.9|
    |  1.2885e+05|  2.2174e+05|  1.3909e+05|      -10232|  1.9832e+05|   1.1e+02|       1.9|
    |  1.2852e+05|  2.1978e+05|  1.3875e+05|      -10224|  1.9795e+05|   1.1e+02|       1.9|
    |  1.2827e+05|  2.1632e+05|  1.3848e+05|      -10216|  1.9653e+05|   1.1e+02|         2|
    |  1.2824e+05|  2.1302e+05|  1.3846e+05|      -10220|  1.9876e+05|   1.1e+02|       1.9|
    |  1.2818e+05|  2.1425e+05|   1.384e+05|      -10216|  1.9779e+05|   1.1e+02|       1.9|
    |  1.2817e+05|  2.1466e+05|  1.3838e+05|      -10215|  1.9752e+05|   1.1e+02|       1.9|
    |  1.2815e+05|  2.1536e+05|  1.3836e+05|      -10213|  1.9717e+05|   1.1e+02|       1.9|
    |  1.2811e+05|  2.1626e+05|  1.3832e+05|      -10211|  1.9686e+05|   1.1e+02|       1.9|
    |  1.2806e+05|  2.1764e+05|  1.3826e+05|      -10208|  1.9668e+05|   1.1e+02|       1.9|
    |  1.2805e+05|  2.1736e+05|  1.3826e+05|      -10208|  1.9717e+05|   1.1e+02|       1.9|
    |  1.2805e+05|  2.1749e+05|  1.3826e+05|      -10208|  1.9693e+05|   1.1e+02|       1.8|
    |  1.2805e+05|  2.1742e+05|  1.3826e+05|      -10208|  1.9697e+05|   1.1e+02|       1.9|
    |  1.2805e+05|  2.1729e+05|  1.3826e+05|      -10208|  1.9703e+05|   1.1e+02|       1.8|
    Optimization result:
          fun: 128044.16324564976
     hess_inv: <25x25 LbfgsInvHessProduct with dtype=float64>
          jac: array([ 21.67021161,   5.72796744,   0.97392078,   3.84598927,
           636.86139094,  10.22583356,   0.        ,   6.14285024,
             0.81411101, -39.71352434,   0.        ,   9.59334241,
             2.14451472,   4.28175272, 767.23922512,  -0.97552918,
            93.48096814,  -2.22591045, 118.52285938,   5.57539791,
            38.26594591,   8.48864576,   0.        , -10.85883055,
             7.64668233])
      message: 'CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH'
         nfev: 27
          nit: 21
         njev: 27
       status: 0
      success: True
            x: array([-9.21034037, -4.46870495, -1.96764908,  1.72425809, -2.30258509,
           -4.60517019,  0.        , -4.60517019, -1.79430812,  2.30258509,
           -2.86003467, -3.56649247, -2.30258509,  1.91041179, -2.30258509,
            0.29155196, -2.30258509,  0.52796843, -2.30258509, -0.58445925,
           -2.30258509, -4.30363654, -0.22314355, -2.54592993, -2.18130617])

    <graphdot.model.gaussian_process.gpr.GaussianProcessRegressor at 0x7f27baa7b4d0>

```
mu = gpr2.predict(train.graphs)
plt.scatter(train[target], mu)
plt.show()
```

```
print('Training set')
print('MAE:', np.mean(np.abs(train[target] - mu)))
print('RMSE:', np.std(train[target] - mu))
```

    Training set
    MAE: 0.7238574928392492
    RMSE: 0.9635062924566815

```
mu_test = gpr2.predict(test.graphs)
plt.scatter(test[target], mu_test)
plt.show()
```

```
print('Test set')
print('MAE:', np.mean(np.abs(test[target] - mu_test)))
print('RMSE:', np.std(test[target] - mu_test))
```

    Test set
    MAE: 0.9561466500156314
    RMSE: 1.2284123729830978

```

```


# Start-to-Finish Example: `GiRaFFE_NRPy` 1D tests

### Author: Patrick Nelson

### Adapted from [Start-to-Finish Example: Head-On Black Hole Collision](../Tutorial-Start_to_Finish-BSSNCurvilinear-Two_BHs_Collide.ipynb)

## This module implements a basic GRFFE code to evolve one-dimensional GRFFE waves.

### NRPy+ Source Code for this module:
* [GiRaFFEfood_NRPy/GiRaFFEfood_NRPy_Exact_Wald.py](../../edit/in_progress/GiRaFFEfood_NRPy/GiRaFFEfood_NRPy_Exact_Wald.py) [\[**tutorial**\]](Tutorial-GiRaFFEfood_NRPy_Exact_Wald.ipynb) Generates Exact Wald initial data
* [GiRaFFEfood_NRPy/GiRaFFEfood_NRPy_Aligned_Rotator.py](../../edit/in_progress/GiRaFFEfood_NRPy/GiRaFFEfood_NRPy_Aligned_Rotator.py) [\[**tutorial**\]](Tutorial-GiRaFFEfood_NRPy_Aligned_Rotator.ipynb) Generates Aligned Rotator initial data
* [GiRaFFEfood_NRPy/GiRaFFEfood_NRPy_1D_tests.py](../../edit/in_progress/GiRaFFEfood_NRPy/GiRaFFEfood_NRPy_1D_tests.py) [\[**tutorial**\]](Tutorial-GiRaFFEfood_NRPy_1D_tests.ipynb) Generates Alfvén Wave initial data.
* [GiRaFFE_NRPy/Afield_flux.py](../../edit/in_progress/GiRaFFE_NRPy/Afield_flux.py) [\[**tutorial**\]](Tutorial-GiRaFFE_NRPy-Afield_flux.ipynb) Generates the expressions to find the flux term of the induction equation.
* [GiRaFFE_NRPy/GiRaFFE_NRPy_A2B.py](../../edit/in_progress/GiRaFFE_NRPy/GiRaFFE_NRPy_A2B.py) [\[**tutorial**\]](Tutorial-GiRaFFE_NRPy-Afield_flux.ipynb) Generates the driver to compute the magnetic field from the vector potential/
* [GiRaFFE_NRPy/GiRaFFE_NRPy_BCs.py](../../edit/in_progress/GiRaFFE_NRPy/GiRaFFE_NRPy_BCs.py) [\[**tutorial**\]](Tutorial-GiRaFFE_NRPy-BCs.ipynb) Generates the code to apply boundary conditions to the vector potential, scalar potential, and three-velocity.
* [GiRaFFE_NRPy/GiRaFFE_NRPy_C2P_P2C.py](../../edit/in_progress/GiRaFFE_NRPy/GiRaFFE_NRPy_C2P_P2C.py) [\[**tutorial**\]](Tutorial-GiRaFFE_NRPy-C2P_P2C.ipynb) Generates the conservative-to-primitive and primitive-to-conservative solvers.
* [GiRaFFE_NRPy/GiRaFFE_NRPy_Metric_Face_Values.py](../../edit/in_progress/GiRaFFE_NRPy/GiRaFFE_NRPy_Metric_Face_Values.py) [\[**tutorial**\]](Tutorial-GiRaFFE_NRPy-Metric_Face_Values.ipynb) Generates code to interpolate metric gridfunctions to cell faces.
* [GiRaFFE_NRPy/GiRaFFE_NRPy_PPM.py](../../edit/in_progress/GiRaFFE_NRPy/GiRaFFE_NRPy_PPM.py) [\[**tutorial**\]](Tutorial-GiRaFFE_NRPy-PPM.ipynb) Genearates code to reconstruct primitive variables on cell faces.
* [GiRaFFE_NRPy/GiRaFFE_NRPy_Source_Terms.py](../../edit/in_progress/GiRaFFE_NRPy/GiRaFFE_NRPy_Source_Terms.py) [\[**tutorial**\]](Tutorial-GiRaFFE_NRPy-Source_Terms.ipynb) Generates the expressions to find the flux term of the Poynting flux evolution equation.
* [GiRaFFE_NRPy/Stilde_flux.py](../../edit/in_progress/GiRaFFE_NRPy/Stilde_flux.py) [\[**tutorial**\]](Tutorial-GiRaFFE_NRPy-Stilde_flux.ipynb) Generates the expressions to find the flux term of the Poynting flux evolution equation.
* [../GRFFE/equations.py](../../edit/GRFFE/equations.py) [\[**tutorial**\]](../Tutorial-GRFFE_Equations-Cartesian.ipynb) Generates code necessary to compute the source terms.
* [../GRHD/equations.py](../../edit/GRHD/equations.py) [\[**tutorial**\]](../Tutorial-GRHD_Equations-Cartesian.ipynb) Generates code necessary to compute the source terms.

Here we use NRPy+ to generate the C source code necessary to set up initial data for an Alfvén wave (see [the original GiRaFFE paper](https://arxiv.org/pdf/1704.00599.pdf)). Then we use it to generate the RHS expressions for [Method of Lines](https://reference.wolfram.com/language/tutorial/NDSolveMethodOfLines.html) time integration based on the [explicit Runge-Kutta fourth-order scheme](https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods) (RK4).

# Table of Contents
$$\label{toc}$$

This notebook is organized as follows

1. [Step 1](#initializenrpy): Set core NRPy+ parameters for numerical grids
1. [Step 2](#grffe): Output C code for GRFFE evolution
    1. [Step 2.a](#mol): Output macros for Method of Lines timestepping
1. [Step 3](#gf_id): Import `GiRaFFEfood_NRPy` initial data modules
1. [Step 4](#cparams): Output C codes needed for declaring and setting Cparameters; also set `free_parameters.h`
1. [Step 5](#mainc): `GiRaFFE_NRPy_standalone.c`: The Main C Code

# Step 1: Set up core functions and parameters for solving  GRFFE equations \[Back to [top](#toc)\]
$$\label{setup}$$

```python
import shutil, os, sys           # Standard Python modules for multiplatform OS-level functions
# First, we'll add the parent directory to the list of directories Python will check for modules.
nrpy_dir_path = os.path.join("..")
if nrpy_dir_path not in sys.path:
    sys.path.append(nrpy_dir_path)

# Step P1: Import needed NRPy+ core modules:
from outputC import outCfunction, lhrh # NRPy+: Core C code output module
import sympy as sp               # SymPy: The Python computer algebra package upon which NRPy+ depends
import finite_difference as fin  # NRPy+: Finite difference C code generation module
import NRPy_param_funcs as par   # NRPy+: Parameter interface
import grid as gri               # NRPy+: Functions having to do with numerical grids
import indexedexp as ixp         # NRPy+: Symbolic indexed expression (e.g., tensors, vectors, etc.) support
import cmdline_helper as cmd     # NRPy+: Multi-platform Python command-line interface

# Step P2: Create C code output directory:
Ccodesdir = os.path.join("GiRaFFE_standalone_Ccodes/")
# First remove C code output directory if it exists
# Courtesy https://stackoverflow.com/questions/303200/how-do-i-remove-delete-a-folder-that-is-not-empty
# !rm -r ScalarWaveCurvilinear_Playground_Ccodes
shutil.rmtree(Ccodesdir, ignore_errors=True)
# Then create a fresh directory
cmd.mkdir(Ccodesdir)

# Step P3: Create executable output directory:
outdir = os.path.join(Ccodesdir,"output/")
cmd.mkdir(Ccodesdir)
cmd.mkdir(outdir)

# Step P5: Set timestepping algorithm (we adopt the Method of Lines)
REAL      = "double"    # Best to use double here.
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.

# Step P6: Set the finite differencing order to 2.
par.set_parval_from_str("finite_difference::FD_CENTDERIVS_ORDER",2)

thismodule = "Start_to_Finish-GiRaFFE_NRPy-1D_tests"
TINYDOUBLE = par.Cparameters("REAL", thismodule, "TINYDOUBLE", 1e-100)

import GiRaFFE_NRPy.GiRaFFE_NRPy_Main_Driver as md
# par.set_paramsvals_value("GiRaFFE_NRPy.GiRaFFE_NRPy_C2P_P2C::enforce_speed_limit_StildeD = False")
par.set_paramsvals_value("GiRaFFE_NRPy.GiRaFFE_NRPy_C2P_P2C::enforce_current_sheet_prescription = False")
```

# Step 2: Output C code for GRFFE evolution \[Back to [top](#toc)\]
$$\label{grffe}$$

We will first write the C codes needed for GRFFE evolution. We have already written a module to generate all these codes and call the functions in the appropriate order, so we will import that here. We will take the slightly unusual step of doing this before we generate the initial data functions because the main driver module will register all the gridfunctions we need. It will also generate functions that, in addition to their normal spot in the MoL timestepping, will need to be called during the initial data step to make sure all the variables are appropriately filled in.

All of this is handled with a single call to `GiRaFFE_NRPy_Main_Driver_generate_all()`, which will register gridfunctions, write all the C code kernels, and write the C code functions to call those.

```python
md.GiRaFFE_NRPy_Main_Driver_generate_all(Ccodesdir)
```

    Output C function calculate_AD_gauge_term_psi6Phi_flux_term_for_RHSs() to file GiRaFFE_standalone_Ccodes/RHSs/calculate_AD_gauge_term_psi6Phi_flux_term_for_RHSs.h
    Output C function calculate_StildeD0_source_term() to file GiRaFFE_standalone_Ccodes/RHSs/calculate_StildeD0_source_term.h
    Output C function calculate_StildeD1_source_term() to file GiRaFFE_standalone_Ccodes/RHSs/calculate_StildeD1_source_term.h
    Output C function calculate_StildeD2_source_term() to file GiRaFFE_standalone_Ccodes/RHSs/calculate_StildeD2_source_term.h
    Output C function calculate_Stilde_rhsD() to file GiRaFFE_standalone_Ccodes/RHSs/calculate_Stilde_rhsD.h
    Output C function GiRaFFE_NRPy_cons_to_prims() to file GiRaFFE_standalone_Ccodes/C2P/GiRaFFE_NRPy_cons_to_prims.h
    Output C function GiRaFFE_NRPy_prims_to_cons() to file GiRaFFE_standalone_Ccodes/C2P/GiRaFFE_NRPy_prims_to_cons.h

## Step 2.a: Output macros for Method of Lines timestepping \[Back to [top](#toc)\]
$$\label{mol}$$

Now, we generate the code to implement the method of lines using the fourth-order Runge-Kutta algorithm.

```python
RK_method = "RK4"

# Step 3: Generate Runge-Kutta-based (RK-based) timestepping code.
#       As described above the Table of Contents, this is a 3-step process:
#       3.A: Evaluate RHSs (RHS_string)
#       3.B: Apply boundary conditions (post_RHS_string, pt 1)
import MoLtimestepping.C_Code_Generation as MoL
from MoLtimestepping.RK_Butcher_Table_Dictionary import Butcher_dict
RK_order  = Butcher_dict[RK_method][1]
cmd.mkdir(os.path.join(Ccodesdir,"MoLtimestepping/"))
MoL.MoL_C_Code_Generation(RK_method,
    RHS_string      = """
GiRaFFE_NRPy_RHSs(&params,auxevol_gfs,RK_INPUT_GFS,RK_OUTPUT_GFS);""",
    post_RHS_string = """
GiRaFFE_NRPy_post_step(&params,xx,auxevol_gfs,RK_OUTPUT_GFS,n+1);\n""",
    outdir = os.path.join(Ccodesdir,"MoLtimestepping/"))

```

# Step 3: Import `GiRaFFEfood_NRPy` initial data modules \[Back to [top](#toc)\]
$$\label{gf_id}$$

With the preliminaries out of the way, we will write the C functions to set up initial data. There are two categories of initial data that must be set: the spacetime metric variables, and the GRFFE plasma variables. We will set up the spacetime first.

```python
# There are several initial data routines we need to test. We'll control which one we use with a string option
initial_data = "AlfvenWave" # Valid options: "AlignedRotator", "AlfvenWave", "FastWave",
                            # "DegenAlfvenWave", "ThreeWaves", "FFE_Breakdown"
spacetime = "flat" # Valid options: "flat"

gammaDD = ixp.zerorank2(DIM=3)
for i in range(3):
    for j in range(3):
        if i==j:
            gammaDD[i][j] = sp.sympify(1) # else: leave as zero
betaU = ixp.zerorank1() # All should be 0
alpha = sp.sympify(1)

# Description and options for this initial data
desc = "Generate a flat spacetime metric."
loopopts_id ="AllPoints" # we don't need to read coordinates for flat spacetime.

name = "set_initial_spacetime_metric_data"
values_to_print = [
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","gammaDD00"),rhs=gammaDD[0][0]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","gammaDD01"),rhs=gammaDD[0][1]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","gammaDD02"),rhs=gammaDD[0][2]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","gammaDD11"),rhs=gammaDD[1][1]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","gammaDD12"),rhs=gammaDD[1][2]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","gammaDD22"),rhs=gammaDD[2][2]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","betaU0"),rhs=betaU[0]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","betaU1"),rhs=betaU[1]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","betaU2"),rhs=betaU[2]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","alpha"),rhs=alpha),
                  ]

outCfunction(
    outfile  = os.path.join(Ccodesdir,name+".h"), desc=desc, name=name,
    params   ="const paramstruct *params,REAL *xx[3],REAL *auxevol_gfs",
    body     = fin.FD_outputC("returnstring",values_to_print,params="outCverbose=False"),
    loopopts = loopopts_id)

```

    Output C function set_initial_spacetime_metric_data() to file GiRaFFE_standalone_Ccodes/set_initial_spacetime_metric_data.h

Now, we will write out the initial data function for the GRFFE variables.

```python
import GiRaFFEfood_NRPy.GiRaFFEfood_NRPy as gf

gf.GiRaFFEfood_NRPy_generate_initial_data(ID_type = initial_data, stagger_enable = True)

if initial_data=="AlfvenWave":
    desc = "Generate Alfven wave 1D initial test data for GiRaFFEfood_NRPy."
elif initial_data=="FastWave":
    desc = "Generate fast wave 1D initial test data for GiRaFFEfood_NRPy."
elif initial_data=="DegenAlfvenWave":
    desc = "Generate degenerate Alfven wave 1D initial test data for GiRaFFEfood_NRPy."
elif initial_data=="ThreeWaves":
    desc = "Generate three waves 1D initial test data for GiRaFFEfood_NRPy."
elif initial_data=="FFE_Breakdown":
    desc = "Generate FFE breakdown 1D initial test data for GiRaFFEfood_NRPy."
elif initial_data=="AlignedRotator":
    desc = "Generate aligned rotator initial test data for GiRaFFEfood_NRPy."
else:
    print("Unsupported Initial Data string "+initial_data+"! Supported ID: AllTests, AlfvenWave, FastWave, DegenAlfvenWave, ThreeWaves, FFE_Breakdown, AlignedRotator, or ExactWald")

name = "initial_data"

values_to_print = [
                   lhrh(lhs=gri.gfaccess("out_gfs","AD0"),rhs=gf.AD[0]),
                   lhrh(lhs=gri.gfaccess("out_gfs","AD1"),rhs=gf.AD[1]),
                   lhrh(lhs=gri.gfaccess("out_gfs","AD2"),rhs=gf.AD[2]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","ValenciavU0"),rhs=gf.ValenciavU[0]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","ValenciavU1"),rhs=gf.ValenciavU[1]),
                   lhrh(lhs=gri.gfaccess("auxevol_gfs","ValenciavU2"),rhs=gf.ValenciavU[2]),
#                    lhrh(lhs=gri.gfaccess("auxevol_gfs","BU0"),rhs=gf.BU[0]),
#                    lhrh(lhs=gri.gfaccess("auxevol_gfs","BU1"),rhs=gf.BU[1]),
#                    lhrh(lhs=gri.gfaccess("auxevol_gfs","BU2"),rhs=gf.BU[2]),
                   lhrh(lhs=gri.gfaccess("out_gfs","psi6Phi"),rhs=sp.sympify(0))
                  ]

outCfunction(
    outfile  = os.path.join(Ccodesdir,name+".h"), desc=desc, name=name,
    params   ="const paramstruct *params,REAL *xx[3],REAL *auxevol_gfs,REAL *out_gfs",
    body     = fin.FD_outputC("returnstring",values_to_print,params="outCverbose=False"),
    loopopts ="AllPoints,Read_xxs")

```

    Output C function initial_data() to file GiRaFFE_standalone_Ccodes/initial_data.h

# Step 4: Output C codes needed for declaring and setting Cparameters; also set `free_parameters.h` \[Back to [top](#toc)\]
$$\label{cparams}$$

Based on declared NRPy+ Cparameters, first we generate `declare_Cparameters_struct.h`, `set_Cparameters_default.h`, and `set_Cparameters[-SIMD].h`.

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

```python
# Step 3.e: Output C codes needed for declaring and setting Cparameters; also set free_parameters.h
# Step 3.e.i: Generate declare_Cparameters_struct.h, set_Cparameters_default.h, and set_Cparameters[-SIMD].h
par.generate_Cparameters_Ccodes(os.path.join(Ccodesdir))

# Step 3.e.ii: Set free_parameters.h
with open(os.path.join(Ccodesdir,"free_parameters.h"),"w") as file:
    file.write("""// Override parameter defaults with values based on command line arguments and NGHOSTS.
params.Nxx0 = atoi(argv[1]);
params.Nxx1 = atoi(argv[2]);
params.Nxx2 = atoi(argv[3]);
params.Nxx_plus_2NGHOSTS0 = params.Nxx0 + 2*NGHOSTS;
params.Nxx_plus_2NGHOSTS1 = params.Nxx1 + 2*NGHOSTS;
params.Nxx_plus_2NGHOSTS2 = params.Nxx2 + 2*NGHOSTS;
// Step 0d: Set up space and time coordinates
// Step 0d.i: Declare \Delta x^i=dxx{0,1,2} and invdxx{0,1,2}, as well as xxmin[3] and xxmax[3]:
const REAL xxmin[3] = {-1.5,-0.1,-0.1};
const REAL xxmax[3] = { 1.5, 0.1, 0.1};
//const REAL xxmin[3] = {-1.5,-1.5,-1.5};
//const REAL xxmax[3] = { 1.5, 1.5, 1.5};

params.dxx0 = (xxmax[0] - xxmin[0]) / ((REAL)params.Nxx0+1);
params.dxx1 = (xxmax[1] - xxmin[1]) / ((REAL)params.Nxx1+1);
params.dxx2 = (xxmax[2] - xxmin[2]) / ((REAL)params.Nxx2+1);
printf("dxx0,dxx1,dxx2 = %.5e,%.5e,%.5e\\n",params.dxx0,params.dxx1,params.dxx2);
params.invdx0 = 1.0 / params.dxx0;
params.invdx1 = 1.0 / params.dxx1;
params.invdx2 = 1.0 / params.dxx2;

const int poison_grids = 0;
// Standard GRFFE parameters:
params.GAMMA_SPEED_LIMIT = 2000.0;
params.diss_strength = 0.1;
""")
if initial_data=="ExactWald":
    with open(os.path.join(out_dir,"free_parameters.h"),"a") as file:
        file.write("""params.r0 = 0.4;
params.a = 0.0;
""")

```

# Step 4: Set up boundary condition functions for chosen singular, curvilinear coordinate system \[Back to [top](#toc)\]
$$\label{bc_functs}$$

Next apply singular, curvilinear coordinate boundary conditions [as documented in the corresponding NRPy+ tutorial notebook](Tutorial-Start_to_Finish-Curvilinear_BCs.ipynb)

...But, for the moment, we're actually just using this because it writes the file `gridfunction_defines.h`.

```python
import CurviBoundaryConditions.CurviBoundaryConditions as cbcs
cbcs.Set_up_CurviBoundaryConditions(os.path.join(Ccodesdir,"boundary_conditions/"),Cparamspath=os.path.join("../"),enable_copy_of_static_Ccodes=False)
```

    Wrote to file "GiRaFFE_standalone_Ccodes/boundary_conditions/parity_conditions_symbolic_dot_products.h"
    Evolved parity: ( AD0:1, AD1:2, AD2:3, StildeD0:1, StildeD1:2, StildeD2:3,
        psi6Phi:0 )

    AuxEvol parity: ( AevolParen:0, BU0:1, BU1:2, BU2:3, B_lU0:1, B_lU1:2,
        B_lU2:3, B_rU0:1, B_rU1:2, B_rU2:3, PhievolParenU0:1, PhievolParenU1:2,
        PhievolParenU2:3, Stilde_flux_HLLED0:1, Stilde_flux_HLLED1:2,
        Stilde_flux_HLLED2:3, ValenciavU0:1, ValenciavU1:2, ValenciavU2:3,
        Valenciav_lU0:1, Valenciav_lU1:2, Valenciav_lU2:3, Valenciav_rU0:1,
        Valenciav_rU1:2, Valenciav_rU2:3, alpha:0, alpha_face:0, betaU0:1,
        betaU1:2, betaU2:3, beta_faceU0:1, beta_faceU1:2, beta_faceU2:3,
        gammaDD00:4, gammaDD01:5, gammaDD02:6, gammaDD11:7, gammaDD12:8,
        gammaDD22:9, gamma_faceDD00:4, gamma_faceDD01:5, gamma_faceDD02:6,
        gamma_faceDD11:7, gamma_faceDD12:8, gamma_faceDD22:9 )
    Wrote to file "GiRaFFE_standalone_Ccodes/boundary_conditions/EigenCoord_Cart_to_xx.h"

# Step 5: `GiRaFFE_NRPy_standalone.c`: The Main C Code \[Back to [top](#toc)\]
$$\label{mainc}$$

```python
# Part P0: Define REAL, set the number of ghost cells NGHOSTS (from NRPy+'s FD_CENTDERIVS_ORDER),
#          and set the CFL_FACTOR (which can be overwritten at the command line)

with open(os.path.join(Ccodesdir,"GiRaFFE_NRPy_REAL__NGHOSTS__CFL_FACTOR.h"), "w") as file:
    file.write("""
// Part P0.a: Set the number of ghost cells, from NRPy+'s FD_CENTDERIVS_ORDER
#define NGHOSTS """+str(3)+"""
#define NGHOSTS_A2B """+str(2)+"""
// Part P0.b: Set the numerical precision (REAL) to double, ensuring all floating point
//            numbers are stored to at least ~16 significant digits
#define REAL """+REAL+"""
// Part P0.c: Set the CFL Factor. Can be overwritten at command line.
REAL CFL_FACTOR = """+str(default_CFL_FACTOR)+";")
```

```python
%%writefile $Ccodesdir/GiRaFFE_NRPy_standalone.c
// Step P0: Define REAL and NGHOSTS; and declare CFL_FACTOR. This header is generated in NRPy+.
#include "GiRaFFE_NRPy_REAL__NGHOSTS__CFL_FACTOR.h"

#include "declare_Cparameters_struct.h"

const int NSKIP_1D_OUTPUT = 1;

// Step P1: Import needed header files
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "time.h"
#include "stdint.h" // Needed for Windows GCC 6.x compatibility
#ifndef M_PI
#define M_PI 3.141592653589793238462643383279502884L
#endif
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.707106781186547524400844362104849039L
#endif

// Step P2: Declare the IDX4S(gf,i,j,k) macro, which enables us to store 4-dimensions of
//           data in a 1D array. In this case, consecutive values of "i"
//           (all other indices held to a fixed value) are consecutive in memory, where
//           consecutive values of "j" (fixing all other indices) are separated by
//           Nxx_plus_2NGHOSTS0 elements in memory. Similarly, consecutive values of
//           "k" are separated by Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1 in memory, etc.
#define IDX4S(g,i,j,k) \
( (i) + Nxx_plus_2NGHOSTS0 * ( (j) + Nxx_plus_2NGHOSTS1 * ( (k) + Nxx_plus_2NGHOSTS2 * (g) ) ) )
#define IDX4ptS(g,idx) ( (idx) + (Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2) * (g) )
#define IDX3S(i,j,k) ( (i) + Nxx_plus_2NGHOSTS0 * ( (j) + Nxx_plus_2NGHOSTS1 * ( (k) ) ) )
#define LOOP_REGION(i0min,i0max, i1min,i1max, i2min,i2max) \
  for(int i2=i2min;i2<i2max;i2++) for(int i1=i1min;i1<i1max;i1++) for(int i0=i0min;i0<i0max;i0++)
#define LOOP_ALL_GFS_GPS(ii) _Pragma("omp parallel for") \
  for(int (ii)=0;(ii)<Nxx_plus_2NGHOSTS_tot*NUM_EVOL_GFS;(ii)++)

// Step P3: Set gridfunction macros
#include "boundary_conditions/gridfunction_defines.h"

// Step P4: Include the RHS, BC, and primitive recovery functions
#include "GiRaFFE_NRPy_Main_Driver.h"

// Step P5: Include the initial data functions
#include "set_initial_spacetime_metric_data.h"
#include "initial_data.h"
// main() function:
// Step 0: Read command-line input, set up grid structure, allocate memory for gridfunctions, set up coordinates
// Step 1: Set up scalar wave initial data
// Step 2: Evolve scalar wave initial data forward in time using Method of Lines with RK4 algorithm,
//         applying quadratic extrapolation outer boundary conditions.
// Step 3: Output relative error between numerical and exact solution.
// Step 4: Free all allocated memory
int main(int argc, const char *argv[]) {
    paramstruct params;
#include "set_Cparameters_default.h"
    // Step 0a: Read command-line input, error out if nonconformant
    if(argc != 4 || atoi(argv[1]) < NGHOSTS || atoi(argv[2]) < NGHOSTS || atoi(argv[3]) < NGHOSTS) {
      printf("Error: Expected three command-line arguments: ./GiRaFFE_NRPy_standalone [Nx] [Ny] [Nz],\n");
      printf("where Nx is the number of grid points in the x direction, and so forth.\n");
      printf("Nx,Ny,Nz MUST BE larger than NGHOSTS (= %d)\n",NGHOSTS);
      exit(1);
    }
    // Step 0c: Set free parameters, overwriting Cparameters defaults
    //          by hand or with command-line input, as desired.
#include "free_parameters.h"
#include "set_Cparameters-nopointer.h"

    //          ... and then set up the numerical grid structure in time:
    const REAL t_final = 0.5;
    const REAL CFL_FACTOR = 0.5; // Set the CFL Factor

    // Step 0c: Allocate memory for gridfunctions
    const int Nxx_plus_2NGHOSTS_tot = Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2;
    // Step 0k: Allocate memory for gridfunctions
#include "MoLtimestepping/RK_Allocate_Memory.h"
    REAL *restrict auxevol_gfs = (REAL *)malloc(sizeof(REAL) * NUM_AUXEVOL_GFS * Nxx_plus_2NGHOSTS_tot);
    REAL *evol_gfs_exact = (REAL *)malloc(sizeof(REAL) * NUM_EVOL_GFS * Nxx_plus_2NGHOSTS_tot);
    REAL *auxevol_gfs_exact  = (REAL *)malloc(sizeof(REAL) * NUM_AUXEVOL_GFS * Nxx_plus_2NGHOSTS_tot);

    // For debugging, it can be useful to set everything to NaN initially.
    if(poison_grids) {
        for(int ii=0;ii<NUM_EVOL_GFS * Nxx_plus_2NGHOSTS_tot;ii++) {
            y_n_gfs[ii] = 1.0/0.0;
            y_nplus1_running_total_gfs[ii] = 1.0/0.0;
            //k_odd_gfs[ii] = 1.0/0.0;
            //k_even_gfs[ii] = 1.0/0.0;
            diagnostic_output_gfs[ii] = 1.0/0.0;
            evol_gfs_exact[ii] = 1.0/0.0;
        }
        for(int ii=0;ii<NUM_AUXEVOL_GFS * Nxx_plus_2NGHOSTS_tot;ii++) {
            auxevol_gfs[ii] = 1.0/0.0;
            auxevol_gfs_exact[ii] = 1.0/0.0;
        }
    }

    // Step 0d: Set up coordinates: Set dx, and then dt based on dx_min and CFL condition
    // This is probably already defined above, but just in case...
    #ifndef MIN
    #define MIN(A, B) ( ((A) < (B)) ? (A) : (B) )
    #endif
    REAL dt = CFL_FACTOR * MIN(dxx0,MIN(dxx1,dxx2)); // CFL condition
    int Nt = (int)(t_final / dt + 0.5); // The number of points in time.
                                        //Add 0.5 to account for C rounding down integers.

    // Step 0e: Set up cell-centered Cartesian coordinate grids
    REAL *xx[3];
    xx[0] = (REAL *)malloc(sizeof(REAL)*Nxx_plus_2NGHOSTS0);
    xx[1] = (REAL *)malloc(sizeof(REAL)*Nxx_plus_2NGHOSTS1);
    xx[2] = (REAL *)malloc(sizeof(REAL)*Nxx_plus_2NGHOSTS2);
    for(int j=0;j<Nxx_plus_2NGHOSTS0;j++) xx[0][j] = xxmin[0] + (j-NGHOSTS+1)*dxx0;
    for(int j=0;j<Nxx_plus_2NGHOSTS1;j++) xx[1][j] = xxmin[1] + (j-NGHOSTS+1)*dxx1;
    for(int j=0;j<Nxx_plus_2NGHOSTS2;j++) xx[2][j] = xxmin[2] + (j-NGHOSTS+1)*dxx2;

    // Step 1: Set up initial data to be exact solution at time=0:
    REAL time = 0.0;
    set_initial_spacetime_metric_data(&params,xx,auxevol_gfs);
    initial_data(&params,xx,auxevol_gfs,y_n_gfs);
    // Fill in  the remaining quantities
    apply_bcs_potential(&params,y_n_gfs);
    driver_A_to_B(&params,y_n_gfs,auxevol_gfs);
    //override_BU_with_old_GiRaFFE(&params,auxevol_gfs,0);
    GiRaFFE_NRPy_prims_to_cons(&params,auxevol_gfs,y_n_gfs);
    apply_bcs_velocity(&params,auxevol_gfs);
    // Extra stack, useful for debugging:
    GiRaFFE_NRPy_cons_to_prims(&params,xx,auxevol_gfs,y_n_gfs);
    //GiRaFFE_NRPy_prims_to_cons(&params,auxevol_gfs,y_n_gfs);
    //GiRaFFE_NRPy_cons_to_prims(&params,xx,auxevol_gfs,y_n_gfs);
    //GiRaFFE_NRPy_prims_to_cons(&params,auxevol_gfs,y_n_gfs);
    //GiRaFFE_NRPy_cons_to_prims(&params,xx,auxevol_gfs,y_n_gfs);

    for(int n=0;n<=Nt;n++) { // Main loop to progress forward in time.
    //for(int n=0;n<=1;n++) { // Main loop to progress forward in time.
        // Step 1a: Set current time to correct value & compute exact solution
        time = ((REAL)n)*dt;

        /* Step 2: Validation: Output relative error between numerical and exact solution, */
        if((n)%NSKIP_1D_OUTPUT ==0) {
            // Step 2c: Output relative error between exact & numerical at center of grid.
            const int i0mid=Nxx_plus_2NGHOSTS0/2;
            const int i1mid=Nxx_plus_2NGHOSTS1/2;
            const int i2mid=Nxx_plus_2NGHOSTS2/2;
            char filename[100];
            sprintf(filename,"out%d-%08d.txt",Nxx0,n);
            FILE *out2D = fopen(filename, "w");
            for(int i0=0;i0<Nxx_plus_2NGHOSTS0;i0++) {
                const int idx = IDX3S(i0,i1mid,i2mid);
                fprintf(out2D,"%.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e\n",
                        xx[0][i0],
                        auxevol_gfs[IDX4ptS(BU0GF,idx)],auxevol_gfs[IDX4ptS(BU1GF,idx)],auxevol_gfs[IDX4ptS(BU2GF,idx)],
                        y_n_gfs[IDX4ptS(AD0GF,idx)],y_n_gfs[IDX4ptS(AD1GF,idx)],y_n_gfs[IDX4ptS(AD2GF,idx)],
                        y_n_gfs[IDX4ptS(STILDED0GF,idx)],y_n_gfs[IDX4ptS(STILDED1GF,idx)],y_n_gfs[IDX4ptS(STILDED2GF,idx)],
                        auxevol_gfs[IDX4ptS(VALENCIAVU0GF,idx)],auxevol_gfs[IDX4ptS(VALENCIAVU1GF,idx)],auxevol_gfs[IDX4ptS(VALENCIAVU2GF,idx)],
                        y_n_gfs[IDX4ptS(PSI6PHIGF,idx)]);
            }
            fclose(out2D);
            // For convergence testing, we'll shift the grid x -> x-1 and output initial data again, giving the exact solution.
            LOOP_REGION(0,Nxx_plus_2NGHOSTS0,0,1,0,1) {
                xx[0][i0] += -mu_AW*time;
                //xx[0][i0] += -time;
            }
            set_initial_spacetime_metric_data(&params,xx,auxevol_gfs_exact);
            initial_data(&params,xx,auxevol_gfs_exact,evol_gfs_exact);
            // Fill in  the remaining quantities
            //driver_A_to_B(&params,evol_gfs_exact,auxevol_gfs_exact);
            GiRaFFE_NRPy_prims_to_cons(&params,auxevol_gfs_exact,evol_gfs_exact);
            // And now, we'll set the grid back to rights.
            LOOP_REGION(0,Nxx_plus_2NGHOSTS0,0,1,0,1) {
                xx[0][i0] -= -mu_AW*time;
                //xx[0][i0] -= -time;
            }
            sprintf(filename,"out%d-%08d_exact.txt",Nxx0,n);
            FILE *out2D_exact = fopen(filename, "w");
            for(int i0=0;i0<Nxx_plus_2NGHOSTS0;i0++) {
                const int idx = IDX3S(i0,i1mid,i2mid);
                fprintf(out2D_exact,"%.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e %.16e\n",
                        xx[0][i0],
                        auxevol_gfs_exact[IDX4ptS(BU0GF,idx)],auxevol_gfs_exact[IDX4ptS(BU1GF,idx)],auxevol_gfs_exact[IDX4ptS(BU2GF,idx)],
                        evol_gfs_exact[IDX4ptS(AD0GF,idx)],evol_gfs_exact[IDX4ptS(AD1GF,idx)],evol_gfs_exact[IDX4ptS(AD2GF,idx)],
                        evol_gfs_exact[IDX4ptS(STILDED0GF,idx)],evol_gfs_exact[IDX4ptS(STILDED1GF,idx)],evol_gfs_exact[IDX4ptS(STILDED2GF,idx)],
                        auxevol_gfs_exact[IDX4ptS(VALENCIAVU0GF,idx)],auxevol_gfs_exact[IDX4ptS(VALENCIAVU1GF,idx)],auxevol_gfs_exact[IDX4ptS(VALENCIAVU2GF,idx)],
                        evol_gfs_exact[IDX4ptS(PSI6PHIGF,idx)]);
            }
            fclose(out2D_exact);

        }

        // Step 3: Evolve scalar wave initial data forward in time using Method of Lines with RK4 algorithm,
        //         applying quadratic extrapolation outer boundary conditions.
        // Step 3.b: Step forward one timestep (t -> t+dt) in time using
        //           chosen RK-like MoL timestepping algorithm
#include "MoLtimestepping/RK_MoL.h"
    } // End main loop to progress forward in time.

    // Step 4: Free all allocated memory
#include "MoLtimestepping/RK_Free_Memory.h"
    free(auxevol_gfs);
    free(auxevol_gfs_exact);
    free(evol_gfs_exact);
    for(int i=0;i<3;i++) free(xx[i]);
    return 0;
}
```

    Writing GiRaFFE_standalone_Ccodes//GiRaFFE_NRPy_standalone.c

```python
cmd.C_compile(os.path.join(Ccodesdir,"GiRaFFE_NRPy_standalone.c"),
              os.path.join(Ccodesdir,"output","GiRaFFE_NRPy_standalone"),compile_mode="safe")
# !gcc -g -O2 -fopenmp GiRaFFE_standalone_Ccodes/GiRaFFE_NRPy_standalone.c -o GiRaFFE_NRPy_standalone -lm

# Change to output directory
os.chdir(outdir)
# Clean up existing output files
cmd.delete_existing_files("out*.txt")
cmd.delete_existing_files("out*.png")
# cmd.Execute(os.path.join(Ccodesdir,"output","GiRaFFE_NRPy_standalone"), "640 16 16", os.path.join(outdir,"out640.txt"))
cmd.Execute("GiRaFFE_NRPy_standalone", "119 7 7","out119.txt")
# cmd.Execute("GiRaFFE_NRPy_standalone", "119 119 119","out119.txt")
# cmd.Execute("GiRaFFE_NRPy_standalone", "239 15 15","out239.txt")
# !OMP_NUM_THREADS=1 valgrind --track-origins=yes -v ./GiRaFFE_NRPy_standalone 1280 32 32
# Return to root directory
os.chdir(os.path.join("../../"))
```

    Compiling executable...
    (EXEC): Executing `gcc -std=gnu99 -O2 -g -fopenmp GiRaFFE_standalone_Ccodes/GiRaFFE_NRPy_standalone.c -o GiRaFFE_standalone_Ccodes/output/GiRaFFE_NRPy_standalone -lm`...
    (BENCH): Finished executing in 2.412449836730957 seconds.
    Finished compilation.
    (EXEC): Executing `taskset -c 0,1,2,3 ./GiRaFFE_NRPy_standalone 119 7 7`...
    (BENCH): Finished executing in 1.211672067642212 seconds.

Now, we will load the data generated by the simulation and plot it in order to test for convergence.

```python
import numpy as np
import matplotlib.pyplot as plt

Data_numer = np.loadtxt(os.path.join("GiRaFFE_standalone_Ccodes","output","out119-00000040.txt"))
# Data_num_2 = np.loadtxt(os.path.join("GiRaFFE_standalone_Ccodes","output","out239-00000080.txt"))
# Data_old = np.loadtxt("/home/penelson/OldCactus/Cactus/exe/ABE-GiRaFFEfood_1D_AlfvenWave/giraffe-grmhd_primitives_bi.x.asc")
# Data_o_2 = np.loadtxt("/home/penelson/OldCactus/Cactus/exe/ABE-GiRaFFEfood_1D_AlfvenWave_2/giraffe-grmhd_primitives_bi.x.asc")
# Data_numer = Data_old[5000:5125,11:15] # The column range is chosen for compatibility with the plotting script.
# Data_num_2 = Data_o_2[19600:19845,11:15] # The column range is chosen for compatibility with the plotting script.
Data_exact = np.loadtxt(os.path.join("GiRaFFE_standalone_Ccodes","output","out119-00000040_exact.txt"))
# Data_exa_2 = np.loadtxt(os.path.join("GiRaFFE_standalone_Ccodes","output","out239-00000080_exact.txt"))

predicted_order = 2.0
column = 3
plt.figure()
# # plt.plot(Data_exact[2:-2,0],np.log2(np.absolute((Data_numer[2:-2,column]-Data_exact[2:-2,column])/\
# #                                     (Data_num_2[2:-2:2,column]-Data_exa_2[2:-2:2,column]))),'.')
plt.plot(Data_exact[:,0],Data_exact[:,column])
plt.plot(Data_exact[:,0],Data_numer[:,column],'.')
# plt.xlim(-0.0,1.0)
# # plt.ylim(-1.0,5.0)
# # plt.ylim(-0.0005,0.0005)
# plt.xlabel("x")
# plt.ylabel("BU2")
plt.show()

# #          0   1     2     3     4     5     6     7          8          9          10            11            12             13
# labels = ["x","BU0","BU1","BU2","AD0","AD1","AD2","StildeD0","StildeD1","StildeD2","ValenciavU0","ValenciavU1","ValenciavU2", "psi6Phi"]
# old_files = ["",
#              "giraffe-grmhd_primitives_bi.x.asc","giraffe-grmhd_primitives_bi.x.asc","giraffe-grmhd_primitives_bi.x.asc",
# #              "giraffe-em_ax.x.asc","giraffe-em_ay.x.asc","giraffe-em_az.x.asc",
#              "cell_centered_Ai.txt","cell_centered_Ai.txt","cell_centered_Ai.txt",
#              "giraffe-grmhd_conservatives.x.asc","giraffe-grmhd_conservatives.x.asc","giraffe-grmhd_conservatives.x.asc",
#              "giraffe-grmhd_primitives_allbutbi.x.asc","giraffe-grmhd_primitives_allbutbi.x.asc","giraffe-grmhd_primitives_allbutbi.x.asc",
#              "giraffe-em_psi6phi.x.asc"]
# column = 5
# column_old = [0,12,13,14,0,1,2,12,13,14,12,13,14,12]
# old_path = "/home/penelson/OldCactus/Cactus/exe/ABE-GiRaFFEfood_1D_AlfvenWave"
# new_path = os.path.join("GiRaFFE_standalone_Ccodes","output")
# data_old = np.loadtxt(os.path.join(old_path,old_files[column]))
# # data_old = data_old[250:375,:]# Select only the second timestep
# # data_old = data_old[125:250,:]# Select only the first timestep
# # data_old = data_old[0:125,:]# Select only the zeroth timestep
# data_new = np.loadtxt(os.path.join(new_path,"out119-00000001.txt"))

# deltaA_old = data_old[125:250,:] - data_old[0:125,:]
# data_new_t0 = np.loadtxt(os.path.join(new_path,"out119-00000000.txt"))
# deltaA_new = data_new[:,:] - data_new_t0[:,:]

# plt.figure()
# # plt.plot(data_new[3:-3,0],data_new[3:-3,column]-data_old[3:-3,column_old[column]])
# # plt.plot(data_new[:,0],data_new[:,column]-((3*np.sin(5*np.pi*data_new[:,0]/np.sqrt(1 - (-0.5)**2))/20 + 23/20)*(data_new[:,0]/2 + np.sqrt(1 - (-0.5)**2)/20 + np.absolute(data_new[:,0] + np.sqrt(1 - (-0.5)**2)/10)/2)*(-1e-100/2 + data_new[:,0]/2 - np.sqrt(1 - (-0.5)**2)/20 - np.absolute(-1e-100 + data_new[:,0] - np.sqrt(1 - (-0.5)**2)/10)/2)/((-1e-100 + data_new[:,0] - np.sqrt(1 - (-0.5)**2)/10)*(1e-100 + data_new[:,0] + np.sqrt(1 - (-0.5)**2)/10)) + 13*(data_new[:,0]/2 - np.sqrt(1 - (-0.5)**2)/20 + np.absolute(data_new[:,0] - np.sqrt(1 - (-0.5)**2)/10)/2)/(10*(1e-100 + data_new[:,0] - np.sqrt(1 - (-0.5)**2)/10)) + (-1e-100/2 + data_new[:,0]/2 + np.sqrt(1 - (-0.5)**2)/20 - np.absolute(-1e-100 + data_new[:,0] + np.sqrt(1 - (-0.5)**2)/10)/2)/(-1e-100 + data_new[:,0] + np.sqrt(1 - (-0.5)**2)/10))/np.sqrt(1 - (-0.5)**2))
# # plt.plot(data_new[1:,0]-(data_new[0,0]-data_new[1,0])/2.0,(data_new[0:-1,column]+data_new[1:,column])/2,'.',label="GiRaFFE_NRPy+injected BU")
# # plt.plot(data_new[1:,0]-(data_new[0,0]-data_new[1,0])/2.0,data_old[1:,column_old[column]],label="old GiRaFFE")
# # -(data_old[0,9]-data_old[1,9])/2.0
# # plt.plot(data_new[3:-3,0],deltaA_new[3:-3,column],'.')
# plt.plot(data_new[3:-3,0],deltaA_old[3:-3,column_old[column]]-deltaA_new[3:-3,column])
# # plt.xlim(-0.1,0.1)
# # plt.ylim(-0.2,0.2)
# plt.legend()
# plt.xlabel(labels[0])
# plt.ylabel(labels[column])
# plt.show()
# # print(np.argmin(deltaA_old[3:-3,column_old[column]]-deltaA_new[3:-3,column]))
```

This code will create an animation of the wave over time.

```python
# import matplotlib.pyplot as plt
from matplotlib.pyplot import savefig
from IPython.display import HTML
import matplotlib.image as mgimg

import glob
import sys
from matplotlib import animation

cmd.delete_existing_files("out119-00*.png")
globby = glob.glob(os.path.join('GiRaFFE_standalone_Ccodes','output','out119-00*.txt'))
file_list = []
for x in sorted(globby):
    file_list.append(x)

number_of_files = int(len(file_list)/2)

for timestep in range(number_of_files):
    fig = plt.figure()
    numer_filename = file_list[2*timestep]
    exact_filename = file_list[2*timestep+1]
    Numer = np.loadtxt(numer_filename)
    Exact = np.loadtxt(exact_filename)

    plt.title("Alfven Wave")
    plt.xlabel("x")
    plt.ylabel("BU2")
    plt.xlim(-0.5,0.5)
    plt.ylim(1.0,1.7)

    plt.plot(Numer[3:-3,0],Numer[3:-3,3],'.',label="Numerical")
    plt.plot(Exact[3:-3,0],Exact[3:-3,3],label="Exact")
    plt.legend()
    savefig(numer_filename+".png",dpi=150)
    plt.close(fig)
    sys.stdout.write("%c[2K" % 27)
    sys.stdout.write("Processing file "+numer_filename+"\r")
    sys.stdout.flush()
```

    Processing file GiRaFFE_standalone_Ccodes/output/out119-00000040.txt

```python
## VISUALIZATION ANIMATION, PART 2: Combine PNGs to generate movie ##
# https://stackoverflow.com/questions/14908576/how-to-remove-frame-from-matplotlib-pyplot-figure-vs-matplotlib-figure-frame
# https://stackoverflow.com/questions/23176161/animating-pngs-in-matplotlib-using-artistanimation
# !rm -f GiRaFFE_NRPy-1D_tests.mp4
cmd.delete_existing_files("GiRaFFE_NRPy-1D_tests.mp4")

fig = plt.figure(frameon=False)
ax = fig.add_axes([0, 0, 1, 1])
ax.axis('off')

myimages = []

for i in range(number_of_files):
    img = mgimg.imread(file_list[2*i]+".png")
    imgplot = plt.imshow(img)
    myimages.append([imgplot])

ani = animation.ArtistAnimation(fig, myimages, interval=100,  repeat_delay=1000)
plt.close()
ani.save('GiRaFFE_NRPy-1D_tests.mp4', fps=5,dpi=150)
```

```python
%%HTML

```

```python
import cmdline_helper as cmd    # NRPy+: Multi-platform Python command-line interface
cmd.output_Jupyter_notebook_to_LaTeXed_PDF("Tutorial-GiRaFFE_NRPy_Main_Driver",location_of_template_file=os.path.join(".."))
```

    Created Tutorial-GiRaFFE_NRPy_Main_Driver.tex, and compiled LaTeX file to
        PDF file Tutorial-GiRaFFE_NRPy_Main_Driver.pdf