{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "provenance": [] }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" } }, "cells": [ { "cell_type": "markdown", "source": [ "# Tutorial on using FEniCSx for solving PDEs\n", "\n", "This is the Google Colab notebook containing a tutorial on using the open source package [FEniCSx](https://fenicsproject.org/) for solving PDEs. This tutorial was prepared by [Andrej Košmrlj](https://www.princeton.edu/~akosmrlj/) with the help of Anvitha Sudhakar for the [DSOFT](https://engage.aps.org/dsoft/home) Short Course on [Computing Soft Matter Across Scales](https://meetings.aps.org/Meeting/MAR23/Session/2E) during the [APS March Meeting 2023](https://meetings.aps.org/Meeting/MAR23/Content/4348)." ], "metadata": { "id": "2R5at1A3goyo" } }, { "cell_type": "markdown", "source": [ "## Layout\n", "\n", "This tutorial is organized as follows:\n", "\n", "* several examples of solving the Poisson's equation in 2d\n", "* one example of solving 2d linear elasticity problem\n", "* one example of solving the Cahn-Hilliard equation in 2d" ], "metadata": { "id": "53cISNZ-jbLQ" } }, { "cell_type": "markdown", "source": [ "## Additional resources\n", "\n", "There is a very detailed [FEniCS tutorial eBook](https://fenicsproject.org/tutorial/). Please note that this eBook was written in 2017 and many of the functions have slightly changed during the transition from FEniCS to FEniCSx. Here are a few demos with explanations that are up to date:\n", "* https://jsdokken.com/dolfinx-tutorial/\n", "* https://docs.fenicsproject.org/dolfinx/v0.6.0/python/demos.html" ], "metadata": { "id": "-HzJLsVup_D9" } }, { "cell_type": "markdown", "source": [ "## Installation\n", "\n", "In order to run the examples below, we need to install the following software:\n", "\n", "* [FEniCSx](https://fenicsproject.org/) via the [FEM on Colab](https://fem-on-colab.github.io/)\n", "* [Gmsh](https://gmsh.info/) package for constructing meshes (also via the [FEM on Colab](https://fem-on-colab.github.io/))\n", "* [PyVista](https://docs.pyvista.org/) package for visualization\n", "\n", "We also recommend installing [Paraview](https://www.paraview.org/) on a local disk for visualization.\n", "\n", "Run the cell below to install the necessary packages. Note that the run will likely crash during the first attempt. If this happens, then rerun the cell to complete the installation." ], "metadata": { "id": "qvnRMu0fj0fq" } }, { "cell_type": "code", "source": [ "!wget \"https://fem-on-colab.github.io/releases/fenicsx-install-real.sh\" -O \"/tmp/fenicsx-install.sh\" && bash \"/tmp/fenicsx-install.sh\"\n", "!wget \"https://fem-on-colab.github.io/releases/gmsh-install.sh\" -O \"/tmp/gmsh-install.sh\" && bash \"/tmp/gmsh-install.sh\"\n", "!apt-get install -qq xvfb\n", "!pip install pyvista panel -q" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "SNSyMWA5gmA8", "outputId": "0a0bccd1-5f63-4664-a708-2c5a158a2a52" }, "execution_count": 1, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "--2023-03-05 15:37:41-- https://fem-on-colab.github.io/releases/fenicsx-install-real.sh\n", "Resolving fem-on-colab.github.io (fem-on-colab.github.io)... 185.199.108.153, 185.199.109.153, 185.199.110.153, ...\n", "Connecting to fem-on-colab.github.io (fem-on-colab.github.io)|185.199.108.153|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 4319 (4.2K) [application/x-sh]\n", "Saving to: ‘/tmp/fenicsx-install.sh’\n", "\n", "\r/tmp/fenicsx-instal 0%[ ] 0 --.-KB/s \r/tmp/fenicsx-instal 100%[===================>] 4.22K --.-KB/s in 0s \n", "\n", "2023-03-05 15:37:41 (39.3 MB/s) - ‘/tmp/fenicsx-install.sh’ saved [4319/4319]\n", "\n", "+ INSTALL_PREFIX=/usr/local\n", "++ awk -F/ '{print NF-1}'\n", "++ echo /usr/local\n", "+ INSTALL_PREFIX_DEPTH=2\n", "+ PROJECT_NAME=fem-on-colab\n", "+ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "+ FENICSX_INSTALLED=/usr/local/share/fem-on-colab/fenicsx.installed\n", "+ [[ ! -f /usr/local/share/fem-on-colab/fenicsx.installed ]]\n", "+ PYBIND11_INSTALL_SCRIPT_PATH=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/3e737e4/releases/pybind11-install.sh\n", "+ [[ https://github.com/fem-on-colab/fem-on-colab.github.io/raw/3e737e4/releases/pybind11-install.sh == http* ]]\n", "+ PYBIND11_INSTALL_SCRIPT_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/3e737e4/releases/pybind11-install.sh\n", "+ PYBIND11_INSTALL_SCRIPT_PATH=/tmp/pybind11-install.sh\n", "+ [[ ! -f /tmp/pybind11-install.sh ]]\n", "+ source /tmp/pybind11-install.sh\n", "++ set -e\n", "++ set -x\n", "++ INSTALL_PREFIX=/usr/local\n", "+++ awk -F/ '{print NF-1}'\n", "+++ echo /usr/local\n", "++ INSTALL_PREFIX_DEPTH=2\n", "++ PROJECT_NAME=fem-on-colab\n", "++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "++ PYBIND11_INSTALLED=/usr/local/share/fem-on-colab/pybind11.installed\n", "++ [[ ! -f /usr/local/share/fem-on-colab/pybind11.installed ]]\n", "++ MPI4PY_INSTALL_SCRIPT_PATH=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/59df126/releases/mpi4py-install.sh\n", "++ [[ https://github.com/fem-on-colab/fem-on-colab.github.io/raw/59df126/releases/mpi4py-install.sh == http* ]]\n", "++ MPI4PY_INSTALL_SCRIPT_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/59df126/releases/mpi4py-install.sh\n", "++ MPI4PY_INSTALL_SCRIPT_PATH=/tmp/mpi4py-install.sh\n", "++ [[ ! -f /tmp/mpi4py-install.sh ]]\n", "++ source /tmp/mpi4py-install.sh\n", "+++ set -e\n", "+++ set -x\n", "+++ INSTALL_PREFIX=/usr/local\n", "++++ awk -F/ '{print NF-1}'\n", "++++ echo /usr/local\n", "+++ INSTALL_PREFIX_DEPTH=2\n", "+++ PROJECT_NAME=fem-on-colab\n", "+++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "+++ MPI4PY_INSTALLED=/usr/local/share/fem-on-colab/mpi4py.installed\n", "+++ [[ ! -f /usr/local/share/fem-on-colab/mpi4py.installed ]]\n", "+++ GCC_INSTALL_SCRIPT_PATH=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/6ffccc3/releases/gcc-install.sh\n", "+++ [[ https://github.com/fem-on-colab/fem-on-colab.github.io/raw/6ffccc3/releases/gcc-install.sh == http* ]]\n", "+++ GCC_INSTALL_SCRIPT_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/6ffccc3/releases/gcc-install.sh\n", "+++ GCC_INSTALL_SCRIPT_PATH=/tmp/gcc-install.sh\n", "+++ [[ ! -f /tmp/gcc-install.sh ]]\n", "+++ source /tmp/gcc-install.sh\n", "++++ set -e\n", "++++ set -x\n", "++++ INSTALL_PREFIX=/usr/local\n", "+++++ echo /usr/local\n", "+++++ awk -F/ '{print NF-1}'\n", "++++ INSTALL_PREFIX_DEPTH=2\n", "++++ PROJECT_NAME=fem-on-colab\n", "++++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "++++ GCC_INSTALLED=/usr/local/share/fem-on-colab/gcc.installed\n", "++++ [[ ! -f /usr/local/share/fem-on-colab/gcc.installed ]]\n", "+++ MPI4PY_ARCHIVE_PATH=https://github.com/fem-on-colab/fem-on-colab/releases/download/mpi4py-20230304-143125-089d188/mpi4py-install.tar.gz\n", "+++ [[ https://github.com/fem-on-colab/fem-on-colab/releases/download/mpi4py-20230304-143125-089d188/mpi4py-install.tar.gz == http* ]]\n", "+++ MPI4PY_ARCHIVE_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab/releases/download/mpi4py-20230304-143125-089d188/mpi4py-install.tar.gz\n", "+++ MPI4PY_ARCHIVE_PATH=/tmp/mpi4py-install.tar.gz\n", "+++ wget https://github.com/fem-on-colab/fem-on-colab/releases/download/mpi4py-20230304-143125-089d188/mpi4py-install.tar.gz -O /tmp/mpi4py-install.tar.gz\n", "--2023-03-05 15:37:41-- https://github.com/fem-on-colab/fem-on-colab/releases/download/mpi4py-20230304-143125-089d188/mpi4py-install.tar.gz\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/fc53c514-dd9d-4170-a33e-77247edda2b6?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153741Z&X-Amz-Expires=300&X-Amz-Signature=4028b51d2d6daac9b1afd510563742fc8879b823df6d510db9124f94667640cc&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dmpi4py-install.tar.gz&response-content-type=application%2Foctet-stream [following]\n", "--2023-03-05 15:37:41-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/fc53c514-dd9d-4170-a33e-77247edda2b6?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153741Z&X-Amz-Expires=300&X-Amz-Signature=4028b51d2d6daac9b1afd510563742fc8879b823df6d510db9124f94667640cc&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dmpi4py-install.tar.gz&response-content-type=application%2Foctet-stream\n", "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.108.133, ...\n", "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.110.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 8542102 (8.1M) [application/octet-stream]\n", "Saving to: ‘/tmp/mpi4py-install.tar.gz’\n", "\n", "/tmp/mpi4py-install 100%[===================>] 8.15M --.-KB/s in 0.1s \n", "\n", "2023-03-05 15:37:42 (84.2 MB/s) - ‘/tmp/mpi4py-install.tar.gz’ saved [8542102/8542102]\n", "\n", "+++ [[ /tmp/mpi4py-install.tar.gz != skip ]]\n", "+++ tar -xzf /tmp/mpi4py-install.tar.gz --strip-components=2 --directory=/usr/local\n", "+++ [[ /tmp/mpi4py-install.tar.gz != skip ]]\n", "+++ command -v mpicc\n", "/usr/local/bin/mpicc\n", "+++ [[ /tmp/mpi4py-install.tar.gz != skip ]]\n", "+++ MPI_LIBS=('libmca*.so*' 'libmpi*.so*' 'libompi*.so*' 'libopen-pal*.so*' 'libopen-rte*.so*' 'ompi*.so*')\n", "+++ for MPI_LIB in \"${MPI_LIBS[@]}\"\n", "+++ rm -f '/usr/lib/libmca*.so*'\n", "+++ rm -f /usr/lib/x86_64-linux-gnu/libmca_common_dstore.so.1 /usr/lib/x86_64-linux-gnu/libmca_common_dstore.so.1.0.2 /usr/lib/x86_64-linux-gnu/libmca_common_monitoring.so /usr/lib/x86_64-linux-gnu/libmca_common_monitoring.so.50 /usr/lib/x86_64-linux-gnu/libmca_common_monitoring.so.50.10.0 /usr/lib/x86_64-linux-gnu/libmca_common_ompio.so /usr/lib/x86_64-linux-gnu/libmca_common_ompio.so.41 /usr/lib/x86_64-linux-gnu/libmca_common_ompio.so.41.19.3 /usr/lib/x86_64-linux-gnu/libmca_common_sm.so /usr/lib/x86_64-linux-gnu/libmca_common_sm.so.40 /usr/lib/x86_64-linux-gnu/libmca_common_sm.so.40.20.0 /usr/lib/x86_64-linux-gnu/libmca_common_verbs.so /usr/lib/x86_64-linux-gnu/libmca_common_verbs.so.40 /usr/lib/x86_64-linux-gnu/libmca_common_verbs.so.40.20.0\n", "+++ ln -fs /usr/local/lib/libmca_common_dstore.so /usr/local/lib/libmca_common_dstore.so.1 /usr/local/lib/libmca_common_dstore.so.1.0.2 /usr/local/lib/libmca_common_monitoring.so /usr/local/lib/libmca_common_monitoring.so.50 /usr/local/lib/libmca_common_monitoring.so.50.20.0 /usr/local/lib/libmca_common_ompio.so /usr/local/lib/libmca_common_ompio.so.41 /usr/local/lib/libmca_common_ompio.so.41.29.4 /usr/local/lib/libmca_common_sm.so /usr/local/lib/libmca_common_sm.so.40 /usr/local/lib/libmca_common_sm.so.40.30.0 /usr/local/lib/libmca_common_verbs.so /usr/local/lib/libmca_common_verbs.so.40 /usr/local/lib/libmca_common_verbs.so.40.30.0 /usr/lib\n", "+++ for MPI_LIB in \"${MPI_LIBS[@]}\"\n", "+++ rm -f '/usr/lib/libmpi*.so*'\n", "+++ rm -f /usr/lib/x86_64-linux-gnu/libmpi_cxx.so /usr/lib/x86_64-linux-gnu/libmpi_cxx.so.40 /usr/lib/x86_64-linux-gnu/libmpi_cxx.so.40.20.1 /usr/lib/x86_64-linux-gnu/libmpi_java.so /usr/lib/x86_64-linux-gnu/libmpi_java.so.40 /usr/lib/x86_64-linux-gnu/libmpi_java.so.40.20.0 /usr/lib/x86_64-linux-gnu/libmpi_mpifh.so /usr/lib/x86_64-linux-gnu/libmpi_mpifh.so.40 /usr/lib/x86_64-linux-gnu/libmpi_mpifh.so.40.20.2 /usr/lib/x86_64-linux-gnu/libmpi++.so /usr/lib/x86_64-linux-gnu/libmpi.so /usr/lib/x86_64-linux-gnu/libmpi.so.40 /usr/lib/x86_64-linux-gnu/libmpi.so.40.20.3 /usr/lib/x86_64-linux-gnu/libmpi_usempif08.so /usr/lib/x86_64-linux-gnu/libmpi_usempif08.so.40 /usr/lib/x86_64-linux-gnu/libmpi_usempif08.so.40.21.0 /usr/lib/x86_64-linux-gnu/libmpi_usempi_ignore_tkr.so /usr/lib/x86_64-linux-gnu/libmpi_usempi_ignore_tkr.so.40 /usr/lib/x86_64-linux-gnu/libmpi_usempi_ignore_tkr.so.40.20.0\n", "+++ ln -fs /usr/local/lib/libmpi_cxx.so /usr/local/lib/libmpi_cxx.so.40 /usr/local/lib/libmpi_cxx.so.40.30.1 /usr/local/lib/libmpi_mpifh.so /usr/local/lib/libmpi_mpifh.so.40 /usr/local/lib/libmpi_mpifh.so.40.30.0 /usr/local/lib/libmpi.so /usr/local/lib/libmpi.so.40 /usr/local/lib/libmpi.so.40.30.5 /usr/local/lib/libmpi_usempif08.so /usr/local/lib/libmpi_usempif08.so.40 /usr/local/lib/libmpi_usempif08.so.40.30.0 /usr/local/lib/libmpi_usempi_ignore_tkr.so /usr/local/lib/libmpi_usempi_ignore_tkr.so.40 /usr/local/lib/libmpi_usempi_ignore_tkr.so.40.30.0 /usr/lib\n", "+++ for MPI_LIB in \"${MPI_LIBS[@]}\"\n", "+++ rm -f '/usr/lib/libompi*.so*'\n", "+++ rm -f /usr/lib/x86_64-linux-gnu/libompitrace.so /usr/lib/x86_64-linux-gnu/libompitrace.so.40 /usr/lib/x86_64-linux-gnu/libompitrace.so.40.20.0\n", "+++ ln -fs /usr/local/lib/libompitrace.so /usr/local/lib/libompitrace.so.40 /usr/local/lib/libompitrace.so.40.30.1 /usr/lib\n", "+++ for MPI_LIB in \"${MPI_LIBS[@]}\"\n", "+++ rm -f '/usr/lib/libopen-pal*.so*'\n", "+++ rm -f /usr/lib/x86_64-linux-gnu/libopen-pal.so /usr/lib/x86_64-linux-gnu/libopen-pal.so.40 /usr/lib/x86_64-linux-gnu/libopen-pal.so.40.20.3\n", "+++ ln -fs /usr/local/lib/libopen-pal.so /usr/local/lib/libopen-pal.so.40 /usr/local/lib/libopen-pal.so.40.30.3 /usr/lib\n", "+++ for MPI_LIB in \"${MPI_LIBS[@]}\"\n", "+++ rm -f '/usr/lib/libopen-rte*.so*'\n", "+++ rm -f /usr/lib/x86_64-linux-gnu/libopen-rte.so /usr/lib/x86_64-linux-gnu/libopen-rte.so.40 /usr/lib/x86_64-linux-gnu/libopen-rte.so.40.20.3\n", "+++ ln -fs /usr/local/lib/libopen-rte.so /usr/local/lib/libopen-rte.so.40 /usr/local/lib/libopen-rte.so.40.30.3 /usr/lib\n", "+++ for MPI_LIB in \"${MPI_LIBS[@]}\"\n", "+++ rm -f '/usr/lib/ompi*.so*'\n", "+++ rm -f '/usr/lib/x86_64-linux-gnu/ompi*.so*'\n", "+++ ln -fs /usr/local/lib/ompi_monitoring_prof.so /usr/lib\n", "+++ mkdir -p /usr/local/share/fem-on-colab\n", "+++ touch /usr/local/share/fem-on-colab/mpi4py.installed\n", "++ PYBIND11_ARCHIVE_PATH=https://github.com/fem-on-colab/fem-on-colab/releases/download/pybind11-20230304-145301-089d188/pybind11-install.tar.gz\n", "++ [[ https://github.com/fem-on-colab/fem-on-colab/releases/download/pybind11-20230304-145301-089d188/pybind11-install.tar.gz == http* ]]\n", "++ PYBIND11_ARCHIVE_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab/releases/download/pybind11-20230304-145301-089d188/pybind11-install.tar.gz\n", "++ PYBIND11_ARCHIVE_PATH=/tmp/pybind11-install.tar.gz\n", "++ wget https://github.com/fem-on-colab/fem-on-colab/releases/download/pybind11-20230304-145301-089d188/pybind11-install.tar.gz -O /tmp/pybind11-install.tar.gz\n", "--2023-03-05 15:37:42-- https://github.com/fem-on-colab/fem-on-colab/releases/download/pybind11-20230304-145301-089d188/pybind11-install.tar.gz\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/d316037f-dfdc-465e-af5c-4cae76b1b723?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153742Z&X-Amz-Expires=300&X-Amz-Signature=648a3e7bf5c8231f78139b96967ec6eb608dffa4c5ad2f2057b491f69af28e0f&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dpybind11-install.tar.gz&response-content-type=application%2Foctet-stream [following]\n", "--2023-03-05 15:37:42-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/d316037f-dfdc-465e-af5c-4cae76b1b723?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153742Z&X-Amz-Expires=300&X-Amz-Signature=648a3e7bf5c8231f78139b96967ec6eb608dffa4c5ad2f2057b491f69af28e0f&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dpybind11-install.tar.gz&response-content-type=application%2Foctet-stream\n", "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 392007 (383K) [application/octet-stream]\n", "Saving to: ‘/tmp/pybind11-install.tar.gz’\n", "\n", "/tmp/pybind11-insta 100%[===================>] 382.82K --.-KB/s in 0.1s \n", "\n", "2023-03-05 15:37:42 (3.36 MB/s) - ‘/tmp/pybind11-install.tar.gz’ saved [392007/392007]\n", "\n", "++ [[ /tmp/pybind11-install.tar.gz != skip ]]\n", "++ rm -rf '/usr/lib/python*/*-packages/pybind11*'\n", "++ rm -rf '/usr/local/lib/python*/*-packages/pybind11*'\n", "++ tar -xzf /tmp/pybind11-install.tar.gz --strip-components=2 --directory=/usr/local\n", "++ mkdir -p /usr/local/share/fem-on-colab\n", "++ touch /usr/local/share/fem-on-colab/pybind11.installed\n", "+ BOOST_INSTALL_SCRIPT_PATH=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/8c2377a/releases/boost-install.sh\n", "+ [[ https://github.com/fem-on-colab/fem-on-colab.github.io/raw/8c2377a/releases/boost-install.sh == http* ]]\n", "+ BOOST_INSTALL_SCRIPT_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/8c2377a/releases/boost-install.sh\n", "+ BOOST_INSTALL_SCRIPT_PATH=/tmp/boost-install.sh\n", "+ [[ ! -f /tmp/boost-install.sh ]]\n", "+ wget https://github.com/fem-on-colab/fem-on-colab.github.io/raw/8c2377a/releases/boost-install.sh -O /tmp/boost-install.sh\n", "--2023-03-05 15:37:42-- https://github.com/fem-on-colab/fem-on-colab.github.io/raw/8c2377a/releases/boost-install.sh\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/8c2377a7981236d85af0de47a1e3a5e46bc08c22/releases/boost-install.sh [following]\n", "--2023-03-05 15:37:43-- https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/8c2377a7981236d85af0de47a1e3a5e46bc08c22/releases/boost-install.sh\n", "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 1855 (1.8K) [text/plain]\n", "Saving to: ‘/tmp/boost-install.sh’\n", "\n", "/tmp/boost-install. 100%[===================>] 1.81K --.-KB/s in 0s \n", "\n", "2023-03-05 15:37:43 (19.9 MB/s) - ‘/tmp/boost-install.sh’ saved [1855/1855]\n", "\n", "+ source /tmp/boost-install.sh\n", "++ set -e\n", "++ set -x\n", "++ INSTALL_PREFIX=/usr/local\n", "+++ echo /usr/local\n", "+++ awk -F/ '{print NF-1}'\n", "++ INSTALL_PREFIX_DEPTH=2\n", "++ PROJECT_NAME=fem-on-colab\n", "++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "++ BOOST_INSTALLED=/usr/local/share/fem-on-colab/boost.installed\n", "++ [[ ! -f /usr/local/share/fem-on-colab/boost.installed ]]\n", "++ GCC_INSTALL_SCRIPT_PATH=/tmp/gcc-install.sh\n", "++ [[ /tmp/gcc-install.sh == http* ]]\n", "++ source /tmp/gcc-install.sh\n", "+++ set -e\n", "+++ set -x\n", "+++ INSTALL_PREFIX=/usr/local\n", "++++ echo /usr/local\n", "++++ awk -F/ '{print NF-1}'\n", "+++ INSTALL_PREFIX_DEPTH=2\n", "+++ PROJECT_NAME=fem-on-colab\n", "+++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "+++ GCC_INSTALLED=/usr/local/share/fem-on-colab/gcc.installed\n", "+++ [[ ! -f /usr/local/share/fem-on-colab/gcc.installed ]]\n", "++ BOOST_ARCHIVE_PATH=https://github.com/fem-on-colab/fem-on-colab/releases/download/boost-20230304-143142-089d188/boost-install.tar.gz\n", "++ [[ https://github.com/fem-on-colab/fem-on-colab/releases/download/boost-20230304-143142-089d188/boost-install.tar.gz == http* ]]\n", "++ BOOST_ARCHIVE_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab/releases/download/boost-20230304-143142-089d188/boost-install.tar.gz\n", "++ BOOST_ARCHIVE_PATH=/tmp/boost-install.tar.gz\n", "++ wget https://github.com/fem-on-colab/fem-on-colab/releases/download/boost-20230304-143142-089d188/boost-install.tar.gz -O /tmp/boost-install.tar.gz\n", "--2023-03-05 15:37:43-- https://github.com/fem-on-colab/fem-on-colab/releases/download/boost-20230304-143142-089d188/boost-install.tar.gz\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/6dbb65f6-6347-4684-b38e-5526c48da5e0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153743Z&X-Amz-Expires=300&X-Amz-Signature=7a815d69abd5a694b70c6281080695eb489b52ebb9ae323125f50ef22ffbfd42&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dboost-install.tar.gz&response-content-type=application%2Foctet-stream [following]\n", "--2023-03-05 15:37:43-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/6dbb65f6-6347-4684-b38e-5526c48da5e0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153743Z&X-Amz-Expires=300&X-Amz-Signature=7a815d69abd5a694b70c6281080695eb489b52ebb9ae323125f50ef22ffbfd42&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dboost-install.tar.gz&response-content-type=application%2Foctet-stream\n", "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.109.133, 185.199.108.133, 185.199.110.133, ...\n", "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.109.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 25332799 (24M) [application/octet-stream]\n", "Saving to: ‘/tmp/boost-install.tar.gz’\n", "\n", "/tmp/boost-install. 100%[===================>] 24.16M 46.9MB/s in 0.5s \n", "\n", "2023-03-05 15:37:44 (46.9 MB/s) - ‘/tmp/boost-install.tar.gz’ saved [25332799/25332799]\n", "\n", "++ [[ /tmp/boost-install.tar.gz != skip ]]\n", "++ tar -xzf /tmp/boost-install.tar.gz --strip-components=2 --directory=/usr/local\n", "++ [[ /tmp/boost-install.tar.gz != skip ]]\n", "++ ln -fs /usr/local/lib/libboost_atomic.so /usr/local/lib/libboost_atomic.so.1.81.0 /usr/local/lib/libboost_chrono.so /usr/local/lib/libboost_chrono.so.1.81.0 /usr/local/lib/libboost_container.so /usr/local/lib/libboost_container.so.1.81.0 /usr/local/lib/libboost_context.so /usr/local/lib/libboost_context.so.1.81.0 /usr/local/lib/libboost_contract.so /usr/local/lib/libboost_contract.so.1.81.0 /usr/local/lib/libboost_coroutine.so /usr/local/lib/libboost_coroutine.so.1.81.0 /usr/local/lib/libboost_date_time.so /usr/local/lib/libboost_date_time.so.1.81.0 /usr/local/lib/libboost_fiber.so /usr/local/lib/libboost_fiber.so.1.81.0 /usr/local/lib/libboost_filesystem.so /usr/local/lib/libboost_filesystem.so.1.81.0 /usr/local/lib/libboost_graph.so /usr/local/lib/libboost_graph.so.1.81.0 /usr/local/lib/libboost_iostreams.so /usr/local/lib/libboost_iostreams.so.1.81.0 /usr/local/lib/libboost_json.a /usr/local/lib/libboost_json.so /usr/local/lib/libboost_json.so.1.81.0 /usr/local/lib/libboost_log_setup.so /usr/local/lib/libboost_log_setup.so.1.81.0 /usr/local/lib/libboost_log.so /usr/local/lib/libboost_log.so.1.81.0 /usr/local/lib/libboost_math_c99f.so /usr/local/lib/libboost_math_c99f.so.1.81.0 /usr/local/lib/libboost_math_c99l.so /usr/local/lib/libboost_math_c99l.so.1.81.0 /usr/local/lib/libboost_math_c99.so /usr/local/lib/libboost_math_c99.so.1.81.0 /usr/local/lib/libboost_math_tr1f.so /usr/local/lib/libboost_math_tr1f.so.1.81.0 /usr/local/lib/libboost_math_tr1l.so /usr/local/lib/libboost_math_tr1l.so.1.81.0 /usr/local/lib/libboost_math_tr1.so /usr/local/lib/libboost_math_tr1.so.1.81.0 /usr/local/lib/libboost_nowide.so /usr/local/lib/libboost_nowide.so.1.81.0 /usr/local/lib/libboost_numpy38.so /usr/local/lib/libboost_numpy38.so.1.81.0 /usr/local/lib/libboost_prg_exec_monitor.so /usr/local/lib/libboost_prg_exec_monitor.so.1.81.0 /usr/local/lib/libboost_program_options.so /usr/local/lib/libboost_program_options.so.1.81.0 /usr/local/lib/libboost_python38.so /usr/local/lib/libboost_python38.so.1.81.0 /usr/local/lib/libboost_random.so /usr/local/lib/libboost_random.so.1.81.0 /usr/local/lib/libboost_regex.so /usr/local/lib/libboost_regex.so.1.81.0 /usr/local/lib/libboost_serialization.so /usr/local/lib/libboost_serialization.so.1.81.0 /usr/local/lib/libboost_stacktrace_addr2line.so /usr/local/lib/libboost_stacktrace_addr2line.so.1.81.0 /usr/local/lib/libboost_stacktrace_basic.so /usr/local/lib/libboost_stacktrace_basic.so.1.81.0 /usr/local/lib/libboost_stacktrace_noop.so /usr/local/lib/libboost_stacktrace_noop.so.1.81.0 /usr/local/lib/libboost_system.so /usr/local/lib/libboost_system.so.1.81.0 /usr/local/lib/libboost_thread.so /usr/local/lib/libboost_thread.so.1.81.0 /usr/local/lib/libboost_timer.so /usr/local/lib/libboost_timer.so.1.81.0 /usr/local/lib/libboost_type_erasure.so /usr/local/lib/libboost_type_erasure.so.1.81.0 /usr/local/lib/libboost_unit_test_framework.so /usr/local/lib/libboost_unit_test_framework.so.1.81.0 /usr/local/lib/libboost_url.so /usr/local/lib/libboost_url.so.1.81.0 /usr/local/lib/libboost_wave.so /usr/local/lib/libboost_wave.so.1.81.0 /usr/local/lib/libboost_wserialization.so /usr/local/lib/libboost_wserialization.so.1.81.0 /usr/lib\n", "++ mkdir -p /usr/local/share/fem-on-colab\n", "++ touch /usr/local/share/fem-on-colab/boost.installed\n", "+ SLEPC4PY_INSTALL_SCRIPT_PATH=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/8b91c4f/releases/slepc4py-install-real.sh\n", "+ [[ https://github.com/fem-on-colab/fem-on-colab.github.io/raw/8b91c4f/releases/slepc4py-install-real.sh == http* ]]\n", "+ SLEPC4PY_INSTALL_SCRIPT_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/8b91c4f/releases/slepc4py-install-real.sh\n", "+ SLEPC4PY_INSTALL_SCRIPT_PATH=/tmp/slepc4py-install.sh\n", "+ [[ ! -f /tmp/slepc4py-install.sh ]]\n", "+ wget https://github.com/fem-on-colab/fem-on-colab.github.io/raw/8b91c4f/releases/slepc4py-install-real.sh -O /tmp/slepc4py-install.sh\n", "--2023-03-05 15:37:46-- https://github.com/fem-on-colab/fem-on-colab.github.io/raw/8b91c4f/releases/slepc4py-install-real.sh\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/8b91c4fc13570500a6c2a85435a867226fa28b1f/releases/slepc4py-install-real.sh [following]\n", "--2023-03-05 15:37:46-- https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/8b91c4fc13570500a6c2a85435a867226fa28b1f/releases/slepc4py-install-real.sh\n", "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 1741 (1.7K) [text/plain]\n", "Saving to: ‘/tmp/slepc4py-install.sh’\n", "\n", "/tmp/slepc4py-insta 100%[===================>] 1.70K --.-KB/s in 0s \n", "\n", "2023-03-05 15:37:47 (18.7 MB/s) - ‘/tmp/slepc4py-install.sh’ saved [1741/1741]\n", "\n", "+ source /tmp/slepc4py-install.sh\n", "++ set -e\n", "++ set -x\n", "++ INSTALL_PREFIX=/usr/local\n", "+++ echo /usr/local\n", "+++ awk -F/ '{print NF-1}'\n", "++ INSTALL_PREFIX_DEPTH=2\n", "++ PROJECT_NAME=fem-on-colab\n", "++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "++ SLEPC4PY_INSTALLED=/usr/local/share/fem-on-colab/slepc4py.installed\n", "++ [[ ! -f /usr/local/share/fem-on-colab/slepc4py.installed ]]\n", "++ PETSC4PY_INSTALL_SCRIPT_PATH=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/e941c24/releases/petsc4py-install-real.sh\n", "++ [[ https://github.com/fem-on-colab/fem-on-colab.github.io/raw/e941c24/releases/petsc4py-install-real.sh == http* ]]\n", "++ PETSC4PY_INSTALL_SCRIPT_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/e941c24/releases/petsc4py-install-real.sh\n", "++ PETSC4PY_INSTALL_SCRIPT_PATH=/tmp/petsc4py-install.sh\n", "++ [[ ! -f /tmp/petsc4py-install.sh ]]\n", "++ wget https://github.com/fem-on-colab/fem-on-colab.github.io/raw/e941c24/releases/petsc4py-install-real.sh -O /tmp/petsc4py-install.sh\n", "--2023-03-05 15:37:47-- https://github.com/fem-on-colab/fem-on-colab.github.io/raw/e941c24/releases/petsc4py-install-real.sh\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/e941c240ac91a0209366e7ffce693789e8443df2/releases/petsc4py-install-real.sh [following]\n", "--2023-03-05 15:37:47-- https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/e941c240ac91a0209366e7ffce693789e8443df2/releases/petsc4py-install-real.sh\n", "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 1793 (1.8K) [text/plain]\n", "Saving to: ‘/tmp/petsc4py-install.sh’\n", "\n", "/tmp/petsc4py-insta 100%[===================>] 1.75K --.-KB/s in 0s \n", "\n", "2023-03-05 15:37:47 (27.7 MB/s) - ‘/tmp/petsc4py-install.sh’ saved [1793/1793]\n", "\n", "++ source /tmp/petsc4py-install.sh\n", "+++ set -e\n", "+++ set -x\n", "+++ INSTALL_PREFIX=/usr/local\n", "++++ echo /usr/local\n", "++++ awk -F/ '{print NF-1}'\n", "+++ INSTALL_PREFIX_DEPTH=2\n", "+++ PROJECT_NAME=fem-on-colab\n", "+++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "+++ PETSC4PY_INSTALLED=/usr/local/share/fem-on-colab/petsc4py.installed\n", "+++ [[ ! -f /usr/local/share/fem-on-colab/petsc4py.installed ]]\n", "+++ H5PY_INSTALL_SCRIPT_PATH=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/d93d7b4/releases/h5py-install.sh\n", "+++ [[ https://github.com/fem-on-colab/fem-on-colab.github.io/raw/d93d7b4/releases/h5py-install.sh == http* ]]\n", "+++ H5PY_INSTALL_SCRIPT_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/d93d7b4/releases/h5py-install.sh\n", "+++ H5PY_INSTALL_SCRIPT_PATH=/tmp/h5py-install.sh\n", "+++ [[ ! -f /tmp/h5py-install.sh ]]\n", "+++ wget https://github.com/fem-on-colab/fem-on-colab.github.io/raw/d93d7b4/releases/h5py-install.sh -O /tmp/h5py-install.sh\n", "--2023-03-05 15:37:47-- https://github.com/fem-on-colab/fem-on-colab.github.io/raw/d93d7b4/releases/h5py-install.sh\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/d93d7b4ea575fa179cbbe3abad47b6807ada9bad/releases/h5py-install.sh [following]\n", "--2023-03-05 15:37:47-- https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/d93d7b4ea575fa179cbbe3abad47b6807ada9bad/releases/h5py-install.sh\n", "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.109.133, ...\n", "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 1723 (1.7K) [text/plain]\n", "Saving to: ‘/tmp/h5py-install.sh’\n", "\n", "/tmp/h5py-install.s 100%[===================>] 1.68K --.-KB/s in 0s \n", "\n", "2023-03-05 15:37:47 (20.4 MB/s) - ‘/tmp/h5py-install.sh’ saved [1723/1723]\n", "\n", "+++ source /tmp/h5py-install.sh\n", "++++ set -e\n", "++++ set -x\n", "++++ INSTALL_PREFIX=/usr/local\n", "+++++ echo /usr/local\n", "+++++ awk -F/ '{print NF-1}'\n", "++++ INSTALL_PREFIX_DEPTH=2\n", "++++ PROJECT_NAME=fem-on-colab\n", "++++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "++++ H5PY_INSTALLED=/usr/local/share/fem-on-colab/h5py.installed\n", "++++ [[ ! -f /usr/local/share/fem-on-colab/h5py.installed ]]\n", "++++ MPI4PY_INSTALL_SCRIPT_PATH=/tmp/mpi4py-install.sh\n", "++++ [[ /tmp/mpi4py-install.sh == http* ]]\n", "++++ source /tmp/mpi4py-install.sh\n", "+++++ set -e\n", "+++++ set -x\n", "+++++ INSTALL_PREFIX=/usr/local\n", "++++++ echo /usr/local\n", "++++++ awk -F/ '{print NF-1}'\n", "+++++ INSTALL_PREFIX_DEPTH=2\n", "+++++ PROJECT_NAME=fem-on-colab\n", "+++++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "+++++ MPI4PY_INSTALLED=/usr/local/share/fem-on-colab/mpi4py.installed\n", "+++++ [[ ! -f /usr/local/share/fem-on-colab/mpi4py.installed ]]\n", "++++ H5PY_ARCHIVE_PATH=https://github.com/fem-on-colab/fem-on-colab/releases/download/h5py-20230304-145247-089d188/h5py-install.tar.gz\n", "++++ [[ https://github.com/fem-on-colab/fem-on-colab/releases/download/h5py-20230304-145247-089d188/h5py-install.tar.gz == http* ]]\n", "++++ H5PY_ARCHIVE_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab/releases/download/h5py-20230304-145247-089d188/h5py-install.tar.gz\n", "++++ H5PY_ARCHIVE_PATH=/tmp/h5py-install.tar.gz\n", "++++ wget https://github.com/fem-on-colab/fem-on-colab/releases/download/h5py-20230304-145247-089d188/h5py-install.tar.gz -O /tmp/h5py-install.tar.gz\n", "--2023-03-05 15:37:47-- https://github.com/fem-on-colab/fem-on-colab/releases/download/h5py-20230304-145247-089d188/h5py-install.tar.gz\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/59f25ead-17a4-4b55-85b2-dadce40ebb66?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153747Z&X-Amz-Expires=300&X-Amz-Signature=f29474be42a64fed10efc66dfef158db1403d8b01db8e57dcd35a76ce247d65e&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dh5py-install.tar.gz&response-content-type=application%2Foctet-stream [following]\n", "--2023-03-05 15:37:47-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/59f25ead-17a4-4b55-85b2-dadce40ebb66?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153747Z&X-Amz-Expires=300&X-Amz-Signature=f29474be42a64fed10efc66dfef158db1403d8b01db8e57dcd35a76ce247d65e&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dh5py-install.tar.gz&response-content-type=application%2Foctet-stream\n", "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.111.133, 185.199.110.133, 185.199.109.133, ...\n", "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.111.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 12392043 (12M) [application/octet-stream]\n", "Saving to: ‘/tmp/h5py-install.tar.gz’\n", "\n", "/tmp/h5py-install.t 100%[===================>] 11.82M --.-KB/s in 0.1s \n", "\n", "2023-03-05 15:37:48 (115 MB/s) - ‘/tmp/h5py-install.tar.gz’ saved [12392043/12392043]\n", "\n", "++++ [[ /tmp/h5py-install.tar.gz != skip ]]\n", "++++ rm -rf '/usr/lib/python*/*-packages/h5py*'\n", "++++ rm -rf /usr/local/lib/python3.8/dist-packages/h5py /usr/local/lib/python3.8/dist-packages/h5py-3.1.0.dist-info /usr/local/lib/python3.8/dist-packages/h5py.libs\n", "++++ tar -xzf /tmp/h5py-install.tar.gz --strip-components=2 --directory=/usr/local\n", "++++ mkdir -p /usr/local/share/fem-on-colab\n", "++++ touch /usr/local/share/fem-on-colab/h5py.installed\n", "+++ apt install -y -qq libblas-dev liblapack-dev\n", "liblapack-dev is already the newest version (3.9.0-1build1).\n", "Suggested packages:\n", " liblapack-doc\n", "The following NEW packages will be installed:\n", " libblas-dev libblas3\n", "0 upgraded, 2 newly installed, 0 to remove and 22 not upgraded.\n", "Need to get 288 kB of archives.\n", "After this operation, 1,589 kB of additional disk space will be used.\n", "Selecting previously unselected package libblas3:amd64.\n", "(Reading database ... 128215 files and directories currently installed.)\n", "Preparing to unpack .../libblas3_3.9.0-1build1_amd64.deb ...\n", "Unpacking libblas3:amd64 (3.9.0-1build1) ...\n", "Selecting previously unselected package libblas-dev:amd64.\n", "Preparing to unpack .../libblas-dev_3.9.0-1build1_amd64.deb ...\n", "Unpacking libblas-dev:amd64 (3.9.0-1build1) ...\n", "Setting up libblas3:amd64 (3.9.0-1build1) ...\n", "Setting up libblas-dev:amd64 (3.9.0-1build1) ...\n", "Processing triggers for libc-bin (2.31-0ubuntu9.9) ...\n", "+++ PETSC4PY_ARCHIVE_PATH=https://github.com/fem-on-colab/fem-on-colab/releases/download/petsc4py-20230304-151008-089d188-real/petsc4py-install.tar.gz\n", "+++ [[ https://github.com/fem-on-colab/fem-on-colab/releases/download/petsc4py-20230304-151008-089d188-real/petsc4py-install.tar.gz == http* ]]\n", "+++ PETSC4PY_ARCHIVE_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab/releases/download/petsc4py-20230304-151008-089d188-real/petsc4py-install.tar.gz\n", "+++ PETSC4PY_ARCHIVE_PATH=/tmp/petsc4py-install.tar.gz\n", "+++ wget https://github.com/fem-on-colab/fem-on-colab/releases/download/petsc4py-20230304-151008-089d188-real/petsc4py-install.tar.gz -O /tmp/petsc4py-install.tar.gz\n", "--2023-03-05 15:37:57-- https://github.com/fem-on-colab/fem-on-colab/releases/download/petsc4py-20230304-151008-089d188-real/petsc4py-install.tar.gz\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/05b034cd-6022-417e-9086-de7801f08195?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153758Z&X-Amz-Expires=300&X-Amz-Signature=4f26ecff1e544f4651ce44cb28239e114a710953890785bdc3f0c3f7316ef550&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dpetsc4py-install.tar.gz&response-content-type=application%2Foctet-stream [following]\n", "--2023-03-05 15:37:58-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/05b034cd-6022-417e-9086-de7801f08195?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153758Z&X-Amz-Expires=300&X-Amz-Signature=4f26ecff1e544f4651ce44cb28239e114a710953890785bdc3f0c3f7316ef550&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dpetsc4py-install.tar.gz&response-content-type=application%2Foctet-stream\n", "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 154960476 (148M) [application/octet-stream]\n", "Saving to: ‘/tmp/petsc4py-install.tar.gz’\n", "\n", "/tmp/petsc4py-insta 100%[===================>] 147.78M 101MB/s in 1.5s \n", "\n", "2023-03-05 15:37:59 (101 MB/s) - ‘/tmp/petsc4py-install.tar.gz’ saved [154960476/154960476]\n", "\n", "+++ [[ /tmp/petsc4py-install.tar.gz != skip ]]\n", "+++ tar -xzf /tmp/petsc4py-install.tar.gz --strip-components=2 --directory=/usr/local\n", "+++ mkdir -p /usr/local/share/fem-on-colab\n", "+++ touch /usr/local/share/fem-on-colab/petsc4py.installed\n", "++ SLEPC4PY_ARCHIVE_PATH=https://github.com/fem-on-colab/fem-on-colab/releases/download/slepc4py-20230304-161248-089d188-real/slepc4py-install.tar.gz\n", "++ [[ https://github.com/fem-on-colab/fem-on-colab/releases/download/slepc4py-20230304-161248-089d188-real/slepc4py-install.tar.gz == http* ]]\n", "++ SLEPC4PY_ARCHIVE_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab/releases/download/slepc4py-20230304-161248-089d188-real/slepc4py-install.tar.gz\n", "++ SLEPC4PY_ARCHIVE_PATH=/tmp/slepc4py-install.tar.gz\n", "++ wget https://github.com/fem-on-colab/fem-on-colab/releases/download/slepc4py-20230304-161248-089d188-real/slepc4py-install.tar.gz -O /tmp/slepc4py-install.tar.gz\n", "--2023-03-05 15:38:06-- https://github.com/fem-on-colab/fem-on-colab/releases/download/slepc4py-20230304-161248-089d188-real/slepc4py-install.tar.gz\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/1dc598ec-7cd0-48f2-9f52-5094074f5f7b?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153806Z&X-Amz-Expires=300&X-Amz-Signature=68383655f6cba25f98d1b5b06f2558317aecfb6dbe5f3604a03b25312fd9c5b5&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dslepc4py-install.tar.gz&response-content-type=application%2Foctet-stream [following]\n", "--2023-03-05 15:38:06-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/1dc598ec-7cd0-48f2-9f52-5094074f5f7b?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153806Z&X-Amz-Expires=300&X-Amz-Signature=68383655f6cba25f98d1b5b06f2558317aecfb6dbe5f3604a03b25312fd9c5b5&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dslepc4py-install.tar.gz&response-content-type=application%2Foctet-stream\n", "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 14059452 (13M) [application/octet-stream]\n", "Saving to: ‘/tmp/slepc4py-install.tar.gz’\n", "\n", "/tmp/slepc4py-insta 100%[===================>] 13.41M 50.7MB/s in 0.3s \n", "\n", "2023-03-05 15:38:06 (50.7 MB/s) - ‘/tmp/slepc4py-install.tar.gz’ saved [14059452/14059452]\n", "\n", "++ [[ /tmp/slepc4py-install.tar.gz != skip ]]\n", "++ tar -xzf /tmp/slepc4py-install.tar.gz --strip-components=2 --directory=/usr/local\n", "++ mkdir -p /usr/local/share/fem-on-colab\n", "++ touch /usr/local/share/fem-on-colab/slepc4py.installed\n", "+ VTK_INSTALL_SCRIPT_PATH=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/a9b4b6f/releases/vtk-install.sh\n", "+ [[ https://github.com/fem-on-colab/fem-on-colab.github.io/raw/a9b4b6f/releases/vtk-install.sh == http* ]]\n", "+ VTK_INSTALL_SCRIPT_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/a9b4b6f/releases/vtk-install.sh\n", "+ VTK_INSTALL_SCRIPT_PATH=/tmp/vtk-install.sh\n", "+ [[ ! -f /tmp/vtk-install.sh ]]\n", "+ wget https://github.com/fem-on-colab/fem-on-colab.github.io/raw/a9b4b6f/releases/vtk-install.sh -O /tmp/vtk-install.sh\n", "--2023-03-05 15:38:07-- https://github.com/fem-on-colab/fem-on-colab.github.io/raw/a9b4b6f/releases/vtk-install.sh\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/a9b4b6f086afb33e0f4eada4b49d58fe5a57fcec/releases/vtk-install.sh [following]\n", "--2023-03-05 15:38:07-- https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/a9b4b6f086afb33e0f4eada4b49d58fe5a57fcec/releases/vtk-install.sh\n", "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 1698 (1.7K) [text/plain]\n", "Saving to: ‘/tmp/vtk-install.sh’\n", "\n", "/tmp/vtk-install.sh 100%[===================>] 1.66K --.-KB/s in 0s \n", "\n", "2023-03-05 15:38:07 (20.5 MB/s) - ‘/tmp/vtk-install.sh’ saved [1698/1698]\n", "\n", "+ source /tmp/vtk-install.sh\n", "++ set -e\n", "++ set -x\n", "++ INSTALL_PREFIX=/usr/local\n", "+++ awk -F/ '{print NF-1}'\n", "+++ echo /usr/local\n", "++ INSTALL_PREFIX_DEPTH=2\n", "++ PROJECT_NAME=fem-on-colab\n", "++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "++ VTK_INSTALLED=/usr/local/share/fem-on-colab/vtk.installed\n", "++ [[ ! -f /usr/local/share/fem-on-colab/vtk.installed ]]\n", "++ H5PY_INSTALL_SCRIPT_PATH=/tmp/h5py-install.sh\n", "++ [[ /tmp/h5py-install.sh == http* ]]\n", "++ source /tmp/h5py-install.sh\n", "+++ set -e\n", "+++ set -x\n", "+++ INSTALL_PREFIX=/usr/local\n", "++++ echo /usr/local\n", "++++ awk -F/ '{print NF-1}'\n", "+++ INSTALL_PREFIX_DEPTH=2\n", "+++ PROJECT_NAME=fem-on-colab\n", "+++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "+++ H5PY_INSTALLED=/usr/local/share/fem-on-colab/h5py.installed\n", "+++ [[ ! -f /usr/local/share/fem-on-colab/h5py.installed ]]\n", "++ VTK_ARCHIVE_PATH=https://github.com/fem-on-colab/fem-on-colab/releases/download/vtk-20230304-151008-089d188/vtk-install.tar.gz\n", "++ [[ https://github.com/fem-on-colab/fem-on-colab/releases/download/vtk-20230304-151008-089d188/vtk-install.tar.gz == http* ]]\n", "++ VTK_ARCHIVE_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab/releases/download/vtk-20230304-151008-089d188/vtk-install.tar.gz\n", "++ VTK_ARCHIVE_PATH=/tmp/vtk-install.tar.gz\n", "++ wget https://github.com/fem-on-colab/fem-on-colab/releases/download/vtk-20230304-151008-089d188/vtk-install.tar.gz -O /tmp/vtk-install.tar.gz\n", "--2023-03-05 15:38:07-- https://github.com/fem-on-colab/fem-on-colab/releases/download/vtk-20230304-151008-089d188/vtk-install.tar.gz\n", "Resolving github.com (github.com)... 140.82.113.3\n", "Connecting to github.com (github.com)|140.82.113.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/5546a654-0b84-4688-a95d-0379ef9b037a?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153807Z&X-Amz-Expires=300&X-Amz-Signature=6e7b83dc229bc15e3dfe8a12fa3561f6bb151ff5cb8bbdfae0e8585aaa0a7a4a&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dvtk-install.tar.gz&response-content-type=application%2Foctet-stream [following]\n", "--2023-03-05 15:38:07-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/5546a654-0b84-4688-a95d-0379ef9b037a?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153807Z&X-Amz-Expires=300&X-Amz-Signature=6e7b83dc229bc15e3dfe8a12fa3561f6bb151ff5cb8bbdfae0e8585aaa0a7a4a&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dvtk-install.tar.gz&response-content-type=application%2Foctet-stream\n", "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 89572488 (85M) [application/octet-stream]\n", "Saving to: ‘/tmp/vtk-install.tar.gz’\n", "\n", "/tmp/vtk-install.ta 100%[===================>] 85.42M 28.0MB/s in 3.0s \n", "\n", "2023-03-05 15:38:10 (28.0 MB/s) - ‘/tmp/vtk-install.tar.gz’ saved [89572488/89572488]\n", "\n", "++ [[ /tmp/vtk-install.tar.gz != skip ]]\n", "++ tar -xzf /tmp/vtk-install.tar.gz --strip-components=2 --directory=/usr/local\n", "++ apt install -y -qq libgl1-mesa-dev libxrender1 xvfb\n", "libxrender1 is already the newest version (1:0.9.10-1).\n", "libxrender1 set to manually installed.\n", "The following additional packages will be installed:\n", " libgles-dev libgles1 libglvnd-dev libopengl-dev\n", "The following NEW packages will be installed:\n", " libgl1-mesa-dev libgles-dev libgles1 libglvnd-dev libopengl-dev xvfb\n", "0 upgraded, 6 newly installed, 0 to remove and 22 not upgraded.\n", "Need to get 860 kB of archives.\n", "After this operation, 3,226 kB of additional disk space will be used.\n", "Selecting previously unselected package libgles1:amd64.\n", "(Reading database ... 128232 files and directories currently installed.)\n", "Preparing to unpack .../0-libgles1_1.3.2-1~ubuntu0.20.04.2_amd64.deb ...\n", "Unpacking libgles1:amd64 (1.3.2-1~ubuntu0.20.04.2) ...\n", "Selecting previously unselected package libgles-dev:amd64.\n", "Preparing to unpack .../1-libgles-dev_1.3.2-1~ubuntu0.20.04.2_amd64.deb ...\n", "Unpacking libgles-dev:amd64 (1.3.2-1~ubuntu0.20.04.2) ...\n", "Selecting previously unselected package libopengl-dev:amd64.\n", "Preparing to unpack .../2-libopengl-dev_1.3.2-1~ubuntu0.20.04.2_amd64.deb ...\n", "Unpacking libopengl-dev:amd64 (1.3.2-1~ubuntu0.20.04.2) ...\n", "Selecting previously unselected package xvfb.\n", "Preparing to unpack .../3-xvfb_2%3a1.20.13-1ubuntu1~20.04.6_amd64.deb ...\n", "Unpacking xvfb (2:1.20.13-1ubuntu1~20.04.6) ...\n", "Selecting previously unselected package libglvnd-dev:amd64.\n", "Preparing to unpack .../4-libglvnd-dev_1.3.2-1~ubuntu0.20.04.2_amd64.deb ...\n", "Unpacking libglvnd-dev:amd64 (1.3.2-1~ubuntu0.20.04.2) ...\n", "Selecting previously unselected package libgl1-mesa-dev:amd64.\n", "Preparing to unpack .../5-libgl1-mesa-dev_21.2.6-0ubuntu0.1~20.04.2_amd64.deb ...\n", "Unpacking libgl1-mesa-dev:amd64 (21.2.6-0ubuntu0.1~20.04.2) ...\n", "Setting up xvfb (2:1.20.13-1ubuntu1~20.04.6) ...\n", "Setting up libgles1:amd64 (1.3.2-1~ubuntu0.20.04.2) ...\n", "Setting up libopengl-dev:amd64 (1.3.2-1~ubuntu0.20.04.2) ...\n", "Setting up libgles-dev:amd64 (1.3.2-1~ubuntu0.20.04.2) ...\n", "Setting up libglvnd-dev:amd64 (1.3.2-1~ubuntu0.20.04.2) ...\n", "Setting up libgl1-mesa-dev:amd64 (21.2.6-0ubuntu0.1~20.04.2) ...\n", "Processing triggers for man-db (2.9.1-1) ...\n", "Processing triggers for libc-bin (2.31-0ubuntu9.9) ...\n", "++ mkdir -p /usr/local/share/fem-on-colab\n", "++ touch /usr/local/share/fem-on-colab/vtk.installed\n", "+ FENICSX_ARCHIVE_PATH=https://github.com/fem-on-colab/fem-on-colab/releases/download/fenicsx-20230304-162529-089d188-real/fenicsx-install.tar.gz\n", "+ [[ https://github.com/fem-on-colab/fem-on-colab/releases/download/fenicsx-20230304-162529-089d188-real/fenicsx-install.tar.gz == http* ]]\n", "+ FENICSX_ARCHIVE_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab/releases/download/fenicsx-20230304-162529-089d188-real/fenicsx-install.tar.gz\n", "+ FENICSX_ARCHIVE_PATH=/tmp/fenicsx-install.tar.gz\n", "+ wget https://github.com/fem-on-colab/fem-on-colab/releases/download/fenicsx-20230304-162529-089d188-real/fenicsx-install.tar.gz -O /tmp/fenicsx-install.tar.gz\n", "--2023-03-05 15:38:23-- https://github.com/fem-on-colab/fem-on-colab/releases/download/fenicsx-20230304-162529-089d188-real/fenicsx-install.tar.gz\n", "Resolving github.com (github.com)... 140.82.121.3\n", "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/288166da-1eb0-4c7e-8d8c-5f243ad32f28?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153824Z&X-Amz-Expires=300&X-Amz-Signature=eefcab1b352a5971c01d60a1769df6077ef00f900d724da977f8411f29e2b15b&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dfenicsx-install.tar.gz&response-content-type=application%2Foctet-stream [following]\n", "--2023-03-05 15:38:24-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/288166da-1eb0-4c7e-8d8c-5f243ad32f28?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153824Z&X-Amz-Expires=300&X-Amz-Signature=eefcab1b352a5971c01d60a1769df6077ef00f900d724da977f8411f29e2b15b&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dfenicsx-install.tar.gz&response-content-type=application%2Foctet-stream\n", "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 20656838 (20M) [application/octet-stream]\n", "Saving to: ‘/tmp/fenicsx-install.tar.gz’\n", "\n", "/tmp/fenicsx-instal 100%[===================>] 19.70M 51.6MB/s in 0.4s \n", "\n", "2023-03-05 15:38:24 (51.6 MB/s) - ‘/tmp/fenicsx-install.tar.gz’ saved [20656838/20656838]\n", "\n", "+ [[ /tmp/fenicsx-install.tar.gz != skip ]]\n", "+ tar -xzf /tmp/fenicsx-install.tar.gz --strip-components=2 --directory=/usr/local\n", "+ mkdir -p /usr/local/share/fem-on-colab\n", "+ touch /usr/local/share/fem-on-colab/fenicsx.installed\n", "+ set +x\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "################################################################################\n", "# This installation is offered by FEM on Colab, an open-source project #\n", "# developed and maintained at Università Cattolica del Sacro Cuore #\n", "# by Dr. Francesco Ballarin. Please see https://fem-on-colab.github.io/ #\n", "# for more details, including a list of further available packages #\n", "# and how to sponsor the development or contribute to the project. #\n", "# #\n", "# We are conducting an informal survey on FEM on Colab usage by our users. #\n", "# The survey is anonymous, and its compilation will typically only require #\n", "# a couple of minutes of your time. If you wish, give us your feedback at #\n", "# https://forms.gle/36sZZWNvPpUv8XWr7 #\n", "################################################################################\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "--2023-03-05 15:38:25-- https://fem-on-colab.github.io/releases/gmsh-install.sh\n", "Resolving fem-on-colab.github.io (fem-on-colab.github.io)... 185.199.110.153, 185.199.109.153, 185.199.108.153, ...\n", "Connecting to fem-on-colab.github.io (fem-on-colab.github.io)|185.199.110.153|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 3495 (3.4K) [application/x-sh]\n", "Saving to: ‘/tmp/gmsh-install.sh’\n", "\n", "/tmp/gmsh-install.s 100%[===================>] 3.41K --.-KB/s in 0s \n", "\n", "2023-03-05 15:38:25 (22.6 MB/s) - ‘/tmp/gmsh-install.sh’ saved [3495/3495]\n", "\n", "+ INSTALL_PREFIX=/usr/local\n", "++ echo /usr/local\n", "++ awk -F/ '{print NF-1}'\n", "+ INSTALL_PREFIX_DEPTH=2\n", "+ PROJECT_NAME=fem-on-colab\n", "+ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "+ GMSH_INSTALLED=/usr/local/share/fem-on-colab/gmsh.installed\n", "+ [[ ! -f /usr/local/share/fem-on-colab/gmsh.installed ]]\n", "+ H5PY_INSTALL_SCRIPT_PATH=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/d93d7b4/releases/h5py-install.sh\n", "+ [[ https://github.com/fem-on-colab/fem-on-colab.github.io/raw/d93d7b4/releases/h5py-install.sh == http* ]]\n", "+ H5PY_INSTALL_SCRIPT_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/d93d7b4/releases/h5py-install.sh\n", "+ H5PY_INSTALL_SCRIPT_PATH=/tmp/h5py-install.sh\n", "+ [[ ! -f /tmp/h5py-install.sh ]]\n", "+ source /tmp/h5py-install.sh\n", "++ set -e\n", "++ set -x\n", "++ INSTALL_PREFIX=/usr/local\n", "+++ echo /usr/local\n", "+++ awk -F/ '{print NF-1}'\n", "++ INSTALL_PREFIX_DEPTH=2\n", "++ PROJECT_NAME=fem-on-colab\n", "++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "++ H5PY_INSTALLED=/usr/local/share/fem-on-colab/h5py.installed\n", "++ [[ ! -f /usr/local/share/fem-on-colab/h5py.installed ]]\n", "+ OCC_INSTALL_SCRIPT_PATH=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/7c106b6/releases/occ-install.sh\n", "+ [[ https://github.com/fem-on-colab/fem-on-colab.github.io/raw/7c106b6/releases/occ-install.sh == http* ]]\n", "+ OCC_INSTALL_SCRIPT_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/7c106b6/releases/occ-install.sh\n", "+ OCC_INSTALL_SCRIPT_PATH=/tmp/occ-install.sh\n", "+ [[ ! -f /tmp/occ-install.sh ]]\n", "+ wget https://github.com/fem-on-colab/fem-on-colab.github.io/raw/7c106b6/releases/occ-install.sh -O /tmp/occ-install.sh\n", "--2023-03-05 15:38:25-- https://github.com/fem-on-colab/fem-on-colab.github.io/raw/7c106b6/releases/occ-install.sh\n", "Resolving github.com (github.com)... 140.82.121.3\n", "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/7c106b6fd97ae5aca28ad550ef13d3319bc5d77b/releases/occ-install.sh [following]\n", "--2023-03-05 15:38:26-- https://raw.githubusercontent.com/fem-on-colab/fem-on-colab.github.io/7c106b6fd97ae5aca28ad550ef13d3319bc5d77b/releases/occ-install.sh\n", "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.111.133, 185.199.110.133, ...\n", "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 1884 (1.8K) [text/plain]\n", "Saving to: ‘/tmp/occ-install.sh’\n", "\n", "/tmp/occ-install.sh 100%[===================>] 1.84K --.-KB/s in 0s \n", "\n", "2023-03-05 15:38:26 (21.4 MB/s) - ‘/tmp/occ-install.sh’ saved [1884/1884]\n", "\n", "+ source /tmp/occ-install.sh\n", "++ set -e\n", "++ set -x\n", "++ INSTALL_PREFIX=/usr/local\n", "+++ echo /usr/local\n", "+++ awk -F/ '{print NF-1}'\n", "++ INSTALL_PREFIX_DEPTH=2\n", "++ PROJECT_NAME=fem-on-colab\n", "++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "++ OCC_INSTALLED=/usr/local/share/fem-on-colab/occ.installed\n", "++ [[ ! -f /usr/local/share/fem-on-colab/occ.installed ]]\n", "++ GCC_INSTALL_SCRIPT_PATH=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/6ffccc3/releases/gcc-install.sh\n", "++ [[ https://github.com/fem-on-colab/fem-on-colab.github.io/raw/6ffccc3/releases/gcc-install.sh == http* ]]\n", "++ GCC_INSTALL_SCRIPT_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab.github.io/raw/6ffccc3/releases/gcc-install.sh\n", "++ GCC_INSTALL_SCRIPT_PATH=/tmp/gcc-install.sh\n", "++ [[ ! -f /tmp/gcc-install.sh ]]\n", "++ source /tmp/gcc-install.sh\n", "+++ set -e\n", "+++ set -x\n", "+++ INSTALL_PREFIX=/usr/local\n", "++++ awk -F/ '{print NF-1}'\n", "++++ echo /usr/local\n", "+++ INSTALL_PREFIX_DEPTH=2\n", "+++ PROJECT_NAME=fem-on-colab\n", "+++ SHARE_PREFIX=/usr/local/share/fem-on-colab\n", "+++ GCC_INSTALLED=/usr/local/share/fem-on-colab/gcc.installed\n", "+++ [[ ! -f /usr/local/share/fem-on-colab/gcc.installed ]]\n", "++ OCC_ARCHIVE_PATH=https://github.com/fem-on-colab/fem-on-colab/releases/download/occ-20230304-143129-089d188/occ-install.tar.gz\n", "++ [[ https://github.com/fem-on-colab/fem-on-colab/releases/download/occ-20230304-143129-089d188/occ-install.tar.gz == http* ]]\n", "++ OCC_ARCHIVE_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab/releases/download/occ-20230304-143129-089d188/occ-install.tar.gz\n", "++ OCC_ARCHIVE_PATH=/tmp/occ-install.tar.gz\n", "++ wget https://github.com/fem-on-colab/fem-on-colab/releases/download/occ-20230304-143129-089d188/occ-install.tar.gz -O /tmp/occ-install.tar.gz\n", "--2023-03-05 15:38:26-- https://github.com/fem-on-colab/fem-on-colab/releases/download/occ-20230304-143129-089d188/occ-install.tar.gz\n", "Resolving github.com (github.com)... 140.82.121.3\n", "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/4d4cbf68-d530-4b1e-94a7-e5c9d0b35524?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153827Z&X-Amz-Expires=300&X-Amz-Signature=3adabdaae746815fbfbafb9587f61d2f15b551a95dfe41c3a0dc7917b465c59c&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Docc-install.tar.gz&response-content-type=application%2Foctet-stream [following]\n", "--2023-03-05 15:38:27-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/4d4cbf68-d530-4b1e-94a7-e5c9d0b35524?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153827Z&X-Amz-Expires=300&X-Amz-Signature=3adabdaae746815fbfbafb9587f61d2f15b551a95dfe41c3a0dc7917b465c59c&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Docc-install.tar.gz&response-content-type=application%2Foctet-stream\n", "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 31532954 (30M) [application/octet-stream]\n", "Saving to: ‘/tmp/occ-install.tar.gz’\n", "\n", "/tmp/occ-install.ta 100%[===================>] 30.07M 75.4MB/s in 0.4s \n", "\n", "2023-03-05 15:38:27 (75.4 MB/s) - ‘/tmp/occ-install.tar.gz’ saved [31532954/31532954]\n", "\n", "++ [[ /tmp/occ-install.tar.gz != skip ]]\n", "++ tar -xzf /tmp/occ-install.tar.gz --strip-components=2 --directory=/usr/local\n", "++ [[ /tmp/occ-install.tar.gz != skip ]]\n", "++ ln -fs /usr/local/lib/libTKBinL.so /usr/local/lib/libTKBinL.so.7 /usr/local/lib/libTKBinL.so.7.6.3 /usr/local/lib/libTKBin.so /usr/local/lib/libTKBin.so.7 /usr/local/lib/libTKBin.so.7.6.3 /usr/local/lib/libTKBinXCAF.so /usr/local/lib/libTKBinXCAF.so.7 /usr/local/lib/libTKBinXCAF.so.7.6.3 /usr/local/lib/libTKBool.so /usr/local/lib/libTKBool.so.7 /usr/local/lib/libTKBool.so.7.6.3 /usr/local/lib/libTKBO.so /usr/local/lib/libTKBO.so.7 /usr/local/lib/libTKBO.so.7.6.3 /usr/local/lib/libTKBRep.so /usr/local/lib/libTKBRep.so.7 /usr/local/lib/libTKBRep.so.7.6.3 /usr/local/lib/libTKCAF.so /usr/local/lib/libTKCAF.so.7 /usr/local/lib/libTKCAF.so.7.6.3 /usr/local/lib/libTKCDF.so /usr/local/lib/libTKCDF.so.7 /usr/local/lib/libTKCDF.so.7.6.3 /usr/local/lib/libTKernel.so /usr/local/lib/libTKernel.so.7 /usr/local/lib/libTKernel.so.7.6.3 /usr/local/lib/libTKFeat.so /usr/local/lib/libTKFeat.so.7 /usr/local/lib/libTKFeat.so.7.6.3 /usr/local/lib/libTKFillet.so /usr/local/lib/libTKFillet.so.7 /usr/local/lib/libTKFillet.so.7.6.3 /usr/local/lib/libTKG2d.so /usr/local/lib/libTKG2d.so.7 /usr/local/lib/libTKG2d.so.7.6.3 /usr/local/lib/libTKG3d.so /usr/local/lib/libTKG3d.so.7 /usr/local/lib/libTKG3d.so.7.6.3 /usr/local/lib/libTKGeomAlgo.so /usr/local/lib/libTKGeomAlgo.so.7 /usr/local/lib/libTKGeomAlgo.so.7.6.3 /usr/local/lib/libTKGeomBase.so /usr/local/lib/libTKGeomBase.so.7 /usr/local/lib/libTKGeomBase.so.7.6.3 /usr/local/lib/libTKHLR.so /usr/local/lib/libTKHLR.so.7 /usr/local/lib/libTKHLR.so.7.6.3 /usr/local/lib/libTKIGES.so /usr/local/lib/libTKIGES.so.7 /usr/local/lib/libTKIGES.so.7.6.3 /usr/local/lib/libTKLCAF.so /usr/local/lib/libTKLCAF.so.7 /usr/local/lib/libTKLCAF.so.7.6.3 /usr/local/lib/libTKMath.so /usr/local/lib/libTKMath.so.7 /usr/local/lib/libTKMath.so.7.6.3 /usr/local/lib/libTKMesh.so /usr/local/lib/libTKMesh.so.7 /usr/local/lib/libTKMesh.so.7.6.3 /usr/local/lib/libTKOffset.so /usr/local/lib/libTKOffset.so.7 /usr/local/lib/libTKOffset.so.7.6.3 /usr/local/lib/libTKPrim.so /usr/local/lib/libTKPrim.so.7 /usr/local/lib/libTKPrim.so.7.6.3 /usr/local/lib/libTKRWMesh.so /usr/local/lib/libTKRWMesh.so.7 /usr/local/lib/libTKRWMesh.so.7.6.3 /usr/local/lib/libTKService.so /usr/local/lib/libTKService.so.7 /usr/local/lib/libTKService.so.7.6.3 /usr/local/lib/libTKShHealing.so /usr/local/lib/libTKShHealing.so.7 /usr/local/lib/libTKShHealing.so.7.6.3 /usr/local/lib/libTKSTEP209.so /usr/local/lib/libTKSTEP209.so.7 /usr/local/lib/libTKSTEP209.so.7.6.3 /usr/local/lib/libTKSTEPAttr.so /usr/local/lib/libTKSTEPAttr.so.7 /usr/local/lib/libTKSTEPAttr.so.7.6.3 /usr/local/lib/libTKSTEPBase.so /usr/local/lib/libTKSTEPBase.so.7 /usr/local/lib/libTKSTEPBase.so.7.6.3 /usr/local/lib/libTKSTEP.so /usr/local/lib/libTKSTEP.so.7 /usr/local/lib/libTKSTEP.so.7.6.3 /usr/local/lib/libTKSTL.so /usr/local/lib/libTKSTL.so.7 /usr/local/lib/libTKSTL.so.7.6.3 /usr/local/lib/libTKTopAlgo.so /usr/local/lib/libTKTopAlgo.so.7 /usr/local/lib/libTKTopAlgo.so.7.6.3 /usr/local/lib/libTKV3d.so /usr/local/lib/libTKV3d.so.7 /usr/local/lib/libTKV3d.so.7.6.3 /usr/local/lib/libTKVCAF.so /usr/local/lib/libTKVCAF.so.7 /usr/local/lib/libTKVCAF.so.7.6.3 /usr/local/lib/libTKVRML.so /usr/local/lib/libTKVRML.so.7 /usr/local/lib/libTKVRML.so.7.6.3 /usr/local/lib/libTKXCAF.so /usr/local/lib/libTKXCAF.so.7 /usr/local/lib/libTKXCAF.so.7.6.3 /usr/local/lib/libTKXDEIGES.so /usr/local/lib/libTKXDEIGES.so.7 /usr/local/lib/libTKXDEIGES.so.7.6.3 /usr/local/lib/libTKXDESTEP.so /usr/local/lib/libTKXDESTEP.so.7 /usr/local/lib/libTKXDESTEP.so.7.6.3 /usr/local/lib/libTKXMesh.so /usr/local/lib/libTKXMesh.so.7 /usr/local/lib/libTKXMesh.so.7.6.3 /usr/local/lib/libTKXmlL.so /usr/local/lib/libTKXmlL.so.7 /usr/local/lib/libTKXmlL.so.7.6.3 /usr/local/lib/libTKXml.so /usr/local/lib/libTKXml.so.7 /usr/local/lib/libTKXml.so.7.6.3 /usr/local/lib/libTKXmlXCAF.so /usr/local/lib/libTKXmlXCAF.so.7 /usr/local/lib/libTKXmlXCAF.so.7.6.3 /usr/local/lib/libTKXSBase.so /usr/local/lib/libTKXSBase.so.7 /usr/local/lib/libTKXSBase.so.7.6.3 /usr/lib\n", "++ apt install -y -qq libfontconfig1 libgl1\n", "libfontconfig1 is already the newest version (2.13.1-2ubuntu3).\n", "libfontconfig1 set to manually installed.\n", "libgl1 is already the newest version (1.3.2-1~ubuntu0.20.04.2).\n", "0 upgraded, 0 newly installed, 0 to remove and 22 not upgraded.\n", "++ mkdir -p /usr/local/share/fem-on-colab\n", "++ touch /usr/local/share/fem-on-colab/occ.installed\n", "+ GMSH_ARCHIVE_PATH=https://github.com/fem-on-colab/fem-on-colab/releases/download/gmsh-20230304-162542-089d188/gmsh-install.tar.gz\n", "+ [[ https://github.com/fem-on-colab/fem-on-colab/releases/download/gmsh-20230304-162542-089d188/gmsh-install.tar.gz == http* ]]\n", "+ GMSH_ARCHIVE_DOWNLOAD=https://github.com/fem-on-colab/fem-on-colab/releases/download/gmsh-20230304-162542-089d188/gmsh-install.tar.gz\n", "+ GMSH_ARCHIVE_PATH=/tmp/gmsh-install.tar.gz\n", "+ wget https://github.com/fem-on-colab/fem-on-colab/releases/download/gmsh-20230304-162542-089d188/gmsh-install.tar.gz -O /tmp/gmsh-install.tar.gz\n", "--2023-03-05 15:38:31-- https://github.com/fem-on-colab/fem-on-colab/releases/download/gmsh-20230304-162542-089d188/gmsh-install.tar.gz\n", "Resolving github.com (github.com)... 140.82.121.3\n", "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/2bb28aca-240d-4770-8da7-366f5dc96d67?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153832Z&X-Amz-Expires=300&X-Amz-Signature=83962c38355cd5fe411c88675dc9592f9b267eac214af6d612b0ef3fd9c75791&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dgmsh-install.tar.gz&response-content-type=application%2Foctet-stream [following]\n", "--2023-03-05 15:38:32-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/370599515/2bb28aca-240d-4770-8da7-366f5dc96d67?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230305%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230305T153832Z&X-Amz-Expires=300&X-Amz-Signature=83962c38355cd5fe411c88675dc9592f9b267eac214af6d612b0ef3fd9c75791&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=370599515&response-content-disposition=attachment%3B%20filename%3Dgmsh-install.tar.gz&response-content-type=application%2Foctet-stream\n", "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 11841370 (11M) [application/octet-stream]\n", "Saving to: ‘/tmp/gmsh-install.tar.gz’\n", "\n", "/tmp/gmsh-install.t 100%[===================>] 11.29M --.-KB/s in 0.1s \n", "\n", "2023-03-05 15:38:32 (100 MB/s) - ‘/tmp/gmsh-install.tar.gz’ saved [11841370/11841370]\n", "\n", "+ [[ /tmp/gmsh-install.tar.gz != skip ]]\n", "+ tar -xzf /tmp/gmsh-install.tar.gz --strip-components=2 --directory=/usr/local\n", "+ [[ /tmp/gmsh-install.tar.gz != skip ]]\n", "+ ln -fs /usr/local/lib/libgmsh.so /usr/local/lib/libgmsh.so.4.11 /usr/local/lib/libgmsh.so.4.11.2 /usr/lib\n", "+ mkdir -p /usr/local/share/fem-on-colab\n", "+ touch /usr/local/share/fem-on-colab/gmsh.installed\n", "+ set +x\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "################################################################################\n", "# This installation is offered by FEM on Colab, an open-source project #\n", "# developed and maintained at Università Cattolica del Sacro Cuore #\n", "# by Dr. Francesco Ballarin. Please see https://fem-on-colab.github.io/ #\n", "# for more details, including a list of further available packages #\n", "# and how to sponsor the development or contribute to the project. #\n", "# #\n", "# We are conducting an informal survey on FEM on Colab usage by our users. #\n", "# The survey is anonymous, and its compilation will typically only require #\n", "# a couple of minutes of your time. If you wish, give us your feedback at #\n", "# https://forms.gle/36sZZWNvPpUv8XWr7 #\n", "################################################################################\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] } ] }, { "cell_type": "markdown", "source": [ "# Basic Poisson equation\n", "\n", "This example illustrates how to:\n", "\n", "- Solve a linear partial differential equation;\n", "- Create a mesh for a disk domain using Gmsh;\n", "- Define a `FunctionSpace`;\n", "- Create and apply Dirichlet boundary conditions;\n", "- Plot the solution using PyVista;\n", "- Compare results with the exact solution;\n", "- Evaluate the value of the function at an arbitrary location." ], "metadata": { "id": "YJw0gSrBpef6" } }, { "cell_type": "markdown", "source": [ "## Equation and problem definition" ], "metadata": { "id": "1GJ5TpByrrs_" } }, { "cell_type": "markdown", "source": [ "The Poisson equation on a unit disk ($R=1$) with Dirichlet boundary conditions:\n", "\n", "
\n", " \\begin{array}{r c c l}\n", " \\nabla^2 u &=& -1 & \\text{in } \\Omega,\\\\\n", " u &=& 0 & \\text{on } \\Gamma.\\\\\n", " \\end{array} \n", "
\n", "\n" ], "metadata": { "id": "Z6FCSm5Jrvzt" } }, { "cell_type": "markdown", "source": [ "![poisson_basic_domain_compressed.png](data:image/png;base64,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)" ], "metadata": { "id": "-YXaxgr8r6Pj" } }, { "cell_type": "markdown", "source": [ "The exact solution in Cartesian coordinates is\n", "$$u({\\bf x})\\equiv u(x,y)=\\frac{1}{4} \\left(1-x^2-y^2\\right).$$" ], "metadata": { "id": "64tvRajEuv9b" } }, { "cell_type": "markdown", "source": [ "### Weak formulation of the problem" ], "metadata": { "id": "anKDY98Tu0nu" } }, { "cell_type": "markdown", "source": [ "In FEniCS, we are solving the weak form of the PDE\n", "$$\\int_\\Omega d{\\bf x} \\ (\\nabla^2 u + 1) \\ v = 0,$$\n", "where $v$ is an arbitrary *test function* that evaluates to $0$ on the boundary points with prescribed values (Dirichlet boundary conditions). Using integration by parts, the above equation can be rewritten as \n", "$$\\int_\\Omega d{\\bf x} \\ (-\\nabla u \\cdot \\nabla v + v) = 0.$$\n" ], "metadata": { "id": "a42kwe-eu3VV" } }, { "cell_type": "markdown", "source": [ "## Implementation" ], "metadata": { "id": "TmFyMVDOu8-k" } }, { "cell_type": "markdown", "source": [ "In order to use the FEniCSx package we need to import the relevant libraries:" ], "metadata": { "id": "Lrs7U5uDsEaN" } }, { "cell_type": "code", "source": [ "from dolfinx import *\n", "import gmsh\n", "from dolfinx.io import gmshio\n", "from mpi4py import MPI\n", "from petsc4py.PETSc import ScalarType\n", "from ufl import *\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import pyvista\n", "pyvista.set_jupyter_backend(\"panel\")\n", "pyvista.start_xvfb()" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 17 }, "id": "w6AXeHbApHpL", "outputId": "29d50fee-ab32-4965-e9c4-dfcaa2f86b56" }, "execution_count": 2, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} } ] }, { "cell_type": "markdown", "source": [ "Define a circular domain and generate a triangular mesh using [Gmsh](https://gmsh.info/). The cell size is set by the $meshSize$ variable." ], "metadata": { "id": "uT64yeRls1t6" } }, { "cell_type": "code", "source": [ "# generate a unit disk mesh via Gmsh\n", "gmsh.initialize()\n", "R = 1. # radius\n", "meshSize = 0.05 # cell size\n", "gdim = 2 # dimensionality of the system\n", "markerId = 1\n", "disk = gmsh.model.occ.addDisk(0, 0, 0, 1, 1)\n", "gmsh.model.occ.synchronize()\n", "gmsh.model.addPhysicalGroup(gdim, [disk], markerId)\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMin\",meshSize)\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMax\",meshSize)\n", "gmsh.model.mesh.generate(gdim)\n", "gmsh_model_rank = 0\n", "mesh_comm = MPI.COMM_WORLD\n", "domain, cell_markers, facet_markers = gmshio.model_to_mesh(gmsh.model, mesh_comm, gmsh_model_rank, gdim=gdim)\n", "gmsh.finalize()\n", "\n", "#visualize the mesh using PyVista\n", "tdim = domain.topology.dim\n", "topology, cell_types, geometry = plot.create_vtk_mesh(domain, tdim)\n", "grid = pyvista.UnstructuredGrid(topology, cell_types, geometry)\n", "plotter = pyvista.Plotter(notebook=True)\n", "plotter.add_mesh(grid, show_edges=True)\n", "plotter.view_xy()\n", "plotter.show()" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 327 }, "id": "UF4mkgYhsXTS", "outputId": "30f86db1-3cb1-4f0e-b531-dfa61720eec1" }, "execution_count": 3, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1003" } } } ] }, { "cell_type": "markdown", "source": [ "Next, we define the `FunctionSpace` that lives on the mesh." ], "metadata": { "id": "g4AqKmzbtq8Q" } }, { "cell_type": "code", "source": [ "#define function space\n", "degreeElements = 1\n", "FS = fem.FunctionSpace(domain, ('Lagrange', degreeElements))" ], "metadata": { "id": "N9BzXlMltpib" }, "execution_count": 4, "outputs": [] }, { "cell_type": "markdown", "source": [ "In this example, we use linear *Lagrange* elements. Higher order elements can be used by changing the value of the `degreeElements`. The list of finite element types that are supported in FEniCS is available here: click this link." ], "metadata": { "id": "S9UmgLNTt06n" } }, { "cell_type": "markdown", "source": [ "To impose Dirichlet boundary condition $u = 0$ on $\\Gamma$, we have to find all facets and degrees of freedom on the boundary." ], "metadata": { "id": "GptgYCDxvhCx" } }, { "cell_type": "code", "source": [ "#impose Dirichlet boundary conditions\n", "tdim = domain.topology.dim\n", "fdim = tdim - 1\n", "domain.topology.create_connectivity(fdim, tdim)\n", "boundary_facets = mesh.exterior_facet_indices(domain.topology)\n", "boundary_dofs = fem.locate_dofs_topological(FS, fdim, boundary_facets)\n", "bc = fem.dirichletbc(ScalarType(0), boundary_dofs, FS)" ], "metadata": { "id": "3oaqq8SstvSr" }, "execution_count": 5, "outputs": [] }, { "cell_type": "markdown", "source": [ "Define function $u(\\bf x)$ and test function $v(\\bf x)$. Note that the initial value for the function is $u(\\bf x)=0$." ], "metadata": { "id": "usH2GAyTwbu_" } }, { "cell_type": "code", "source": [ "#define function u and test function v\n", "u = fem.Function(FS)\n", "v = TestFunction(FS)" ], "metadata": { "id": "1LLJ-61vwcGa" }, "execution_count": 6, "outputs": [] }, { "cell_type": "markdown", "source": [ "The weak formulation of the problem$$\\int_\\Omega d{\\bf x} \\ (-\\nabla u \\cdot \\nabla v + v) = 0,$$\n", "where `dx` describes the integration over the domain $\\Omega$" ], "metadata": { "id": "uaMq31JUwiRS" } }, { "cell_type": "code", "source": [ "# weak formulation of the problem\n", "Res = -dot(grad(u), grad(v))*dx + v*dx" ], "metadata": { "id": "xSsD7ZHqweii" }, "execution_count": 7, "outputs": [] }, { "cell_type": "markdown", "source": [ "Solve the problem `Res=0` using the Dirichlet boundary conditions `bc` and store the solution in the function `u`." ], "metadata": { "id": "5aBR0l-rwz4Z" } }, { "cell_type": "code", "source": [ "# solve the problem\n", "problem = fem.petsc.NonlinearProblem(Res, u, bcs=[bc])\n", "solver = nls.petsc.NewtonSolver(MPI.COMM_WORLD, problem)\n", "solver.solve(u)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "vj9eHLB6wpIc", "outputId": "f13575cd-0b4e-4dc0-f4c6-b86c982cd126" }, "execution_count": 8, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(1, True)" ] }, "metadata": {}, "execution_count": 8 } ] }, { "cell_type": "markdown", "source": [ "> Note that we here used the Newton-Raphson method, which can be used to solve both linear and non-linear problems. Consult with the FEniCSx documentation for other solver options.\n", "" ], "metadata": { "id": "o4806PqNzvgm" } }, { "cell_type": "markdown", "source": [ "The solution $u({\\bf x})$ can be plotted using the [PyVista](https://docs.pyvista.org/) package." ], "metadata": { "id": "I61EaHtlz8E6" } }, { "cell_type": "code", "source": [ "def plotScalarFunction(u):\n", " u_topology, u_cell_types, u_geometry = plot.create_vtk_mesh(FS)\n", " u_grid = pyvista.UnstructuredGrid(u_topology, u_cell_types, u_geometry)\n", " u_grid.point_data[\"u\"] = u.x.array.real\n", " u_grid.set_active_scalars(\"u\")\n", " u_plotter = pyvista.Plotter(notebook=True)\n", " u_plotter.add_mesh(u_grid, show_edges=True)\n", " u_plotter.view_xy()\n", " u_plotter.show()\n", "\n", "plotScalarFunction(u)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 327 }, "id": "hstGY-J0zWeY", "outputId": "80b3ccd9-f3d5-4c5f-eab2-23a22385f798" }, "execution_count": 9, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='100...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1008" } } } ] }, { "cell_type": "markdown", "source": [ "The accuracy of the obtained solution $u({\\bf x})$ can be compared against the exact solution\n", "$u({\\bf x})=\\frac{1}{4} \\left(1-x^2-y^2\\right)$ by calculating the $L^2$ norm of the difference:" ], "metadata": { "id": "bm0IxyuY1V-c" } }, { "cell_type": "code", "source": [ "# exact solution\n", "uExact = fem.Function(FS)\n", "uExact.interpolate(lambda x: (1 - x[0]**2 - x[1]**2)/4)\n", "\n", "L2_error = fem.form(inner(u - uExact, u - uExact) * dx)\n", "error_local = fem.assemble_scalar(L2_error)\n", "print(error_local)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "0prm4O-M0Zd2", "outputId": "490a4381-c56a-4f21-bbd7-dcfaed5c04b5" }, "execution_count": 10, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "2.3554633171513374e-10\n" ] } ] }, { "cell_type": "markdown", "source": [ "The exact solution is interpolated to the `FunctionSpace` using the anonymous lambda function, where `x[0]` and `x[1]` refer to the $x$ and $y$ coordinates, respectively. " ], "metadata": { "id": "Ra4BLhNd1riu" } }, { "cell_type": "markdown", "source": [ "Below we follow [this online tutorial](https://jsdokken.com/dolfinx-tutorial/chapter1/membrane_code.html) to evaluate $u(x,0)$ along the $x$ coordinate axis and plot it with the `matplotlib` function." ], "metadata": { "id": "LVvnLtY62Vyg" } }, { "cell_type": "code", "source": [ "# plot solution at u(x,0)\n", "tol = 0.001 # Avoid hitting the outside of the domain\n", "x = np.linspace(-1 + tol, 1 - tol, 101)\n", "points = np.zeros((3, 101))\n", "points[0] = x\n", "u_values = []\n", "p_values = []\n", "\n", "from dolfinx import geometry\n", "bb_tree = geometry.BoundingBoxTree(domain, domain.topology.dim)\n", "cells = []\n", "points_on_proc = []\n", "# Find cells whose bounding-box collide with the the points\n", "cell_candidates = geometry.compute_collisions(bb_tree, points.T)\n", "# Choose one of the cells that contains the point\n", "colliding_cells = geometry.compute_colliding_cells(domain, cell_candidates, points.T)\n", "for i, point in enumerate(points.T):\n", " if len(colliding_cells.links(i))>0:\n", " points_on_proc.append(point)\n", " cells.append(colliding_cells.links(i)[0])\n", " \n", "points_on_proc = np.array(points_on_proc, dtype=np.float64)\n", "u_values = u.eval(points_on_proc, cells)\n", "\n", "plt.plot(x,u_values,'k-')\n", "plt.plot(x,(1-x*x)/4,'r--')\n", "plt.xlabel('$x$')\n", "plt.ylabel('$u(x,0)$')\n", "plt.legend(['FEM','exact'])\n", "plt.show()" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 279 }, "id": "L-bZL8MG1bvl", "outputId": "2f28c78a-093f-4190-a210-ca8faeee26de" }, "execution_count": 11, "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "
" ], "image/png": "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HqVVq1bs2LGDLVu2cOutt7Js2TJKly5NQkICpUqVYsCAAdx88830ujDTxX52QERWq2pERsv73Uh5xlzM6d272dOyJc2OHOHbGjW44fffKVaypNOx8ryOY8ey9frrOdC1K02ffpr1y5fTeO5cCAx0OlquFxUVxerVq2nevDmQPrZF2bJlefbZZ2nevDkhISG8+eabQHrXTKNGjeKXX34hICCAuLg4Dh06xM8//8ztt99O6dKlASjlpav/rFiYXCEuLo65V1/NoCNH+L5PH27+9FO7b8KH6rZrR8Lu3XwfEUHXefOY1qsXA7/8ksC8VjAudSRQuPCl55cunemRxIVUlf79+/Pyyy//Y/qBAwc4ffo0586dIykpiSJFivDJJ59w5MgRVq9eTVBQEGFhYSQlJWVrezlhbRbG721Zu5ZWrVox6vRpot95h66ffWaFwgGlypen4549TOzRg/u++YZevXrx16lTTsfK1dq3b8+XX37J4cPpg4MmJCSwd+9e7r//fp5//nn69evHU089BcCJEycoW7YsQUFBLFq0iL179wLQrl07vvjii7/HtEhISACgWLFinPLk7+diPQzm5of1Opt3bB0xQncGBGjjsmV17dq1TscxLhMnTtTGoDEhIXpk8WKn41w2f+h1dtasWdq4cWNt2LChNm3aVMeOHas9e/ZUVdWUlBRt0aKFRkVF6ZEjR7RVq1baoEEDHTBggNapU0d3796tqqoffvih1q9fXxs1aqT9+/dXVdVff/1V69atq+Hh4RoTE/Ov7Wa311lr4Db+SZV1/foR/tlnLC9ShEorVlC5QQOnUxk3iydMoM4jjxASEMBfs2ZR8fbbnY6UbRk18uYX2W3gttNQxu9oairR119P+GefEVWmDHV27rRC4YduGD6cA199RTxQ6o472PXWW05HMl5kxcL4FVVlXps2RCxdyvwaNbhu715KlivndCxzEU169iR1yRJ2BAVR5eGH2WgFI8+yYmH8RlpaGg888AB3LVvGrHbt6LRtG8GFCjkdy2Si1nXXUWr9eqaGhnLdk0+ycOFCpyNlS148FZ+Zy/mZrVgYv5D6119826wZH77zDkNHjKD3Tz8RkNcuy8zDKtWty+1bthBWqxYDbrqJNcOHOx0pS0JCQoiPj89XBUNViY+PJyQkJFvr2X0WxnGpf/3Flpo16X7gAO/37Uvfl16y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\n" }, "metadata": { "needs_background": "light" } } ] }, { "cell_type": "code", "source": [], "metadata": { "id": "iIPTTSXJ3Gwt" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "# Basic Poisson equation with a time-dependent source term\n", "\n", "This example builds on the *basic Poisson equation* example ([click this link](#poissonBasic)). It illustrates how to:\n", "\n", "- Efficiently solve a linear partial differential equation multiple times;\n", "- Assign updated values to the `Constant` objects and user-defined classes that are interpolated to the `FunctionSpace`." ], "metadata": { "id": "Q-4WhshG44Yh" } }, { "cell_type": "markdown", "source": [ "## Equation and problem definition" ], "metadata": { "id": "3pcZjxFI6jn4" } }, { "cell_type": "markdown", "source": [ "The Poisson equation on a unit disk ($R=1$) with Dirichlet boundary conditions:\n", "\n", "
\n", " \\begin{array}{r c c l}\n", " \\nabla^2 u &=& -f(t) & \\text{in } \\Omega,\\\\\n", " u &=& 0 & \\text{on } \\Gamma,\\\\\n", " \\end{array} \n", "
\n", "where $f(t)=t$." ], "metadata": { "id": "_HXxJPJW6mXQ" } }, { "cell_type": "markdown", "source": [ "![poisson_basic_domain_compressed.png](data:image/png;base64,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)" ], "metadata": { "id": "Vf18PGrt6qbP" } }, { "cell_type": "markdown", "source": [ "### Weak formulation of the problem" ], "metadata": { "id": "8XqM8mWi6tKb" } }, { "cell_type": "markdown", "source": [ "In FEniCS, we are solving the weak form of the PDE\n", "$$\\int_\\Omega d{\\bf x} \\ (\\nabla^2 u + f(t)) \\ v = 0,$$\n", "where $v$ is an arbitrary *test function* that evaluates to $0$ on the boundary points with prescribed values (Dirichlet boundary conditions). Using the integration by parts, the above equation can be rewritten as \n", "$$\\int_\\Omega d{\\bf x} \\ (-\\nabla u \\cdot \\nabla v + f(t) v) = 0.$$" ], "metadata": { "id": "ci_z2wjT6vx9" } }, { "cell_type": "markdown", "source": [ "## Implementation" ], "metadata": { "id": "2y9g7CHF602i" } }, { "cell_type": "markdown", "source": [ "Following the same steps as in the *basic Poisson equation* example ([click this link](#poissonBasic)), we import relevant libraries, generate mesh, define function space, impose the Dirichlet boundary conditions, and define the function $u$ and the test function $v$." ], "metadata": { "id": "9b3p0RgG65j0" } }, { "cell_type": "code", "source": [ "from dolfinx import *\n", "import gmsh\n", "from dolfinx.io import gmshio\n", "from mpi4py import MPI\n", "from petsc4py.PETSc import ScalarType\n", "from ufl import *\n", "import pyvista\n", "pyvista.start_xvfb()\n", "\n", "\n", "gmsh.initialize()\n", "R = 1. # radius\n", "meshSize = 0.05 # cell size\n", "gdim = 2 # dimensionality of the system\n", "markerId = 1\n", "disk = gmsh.model.occ.addDisk(0, 0, 0, 1, 1)\n", "gmsh.model.occ.synchronize()\n", "gmsh.model.addPhysicalGroup(gdim, [disk], markerId)\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMin\",meshSize)\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMax\",meshSize)\n", "gmsh.model.mesh.generate(gdim)\n", "gmsh_model_rank = 0\n", "mesh_comm = MPI.COMM_WORLD\n", "domain, cell_markers, facet_markers = gmshio.model_to_mesh(gmsh.model, mesh_comm, gmsh_model_rank, gdim=gdim)\n", "gmsh.finalize()\n", "\n", "\n", "def plotScalarFunction(u, clim):\n", " u_topology, u_cell_types, u_geometry = plot.create_vtk_mesh(FS)\n", " u_grid = pyvista.UnstructuredGrid(u_topology, u_cell_types, u_geometry)\n", " u_grid.point_data[\"u\"] = u.x.array.real\n", " u_grid.set_active_scalars(\"u\")\n", " u_plotter = pyvista.Plotter(notebook=True)\n", " u_plotter.add_mesh(u_grid, clim=clim,show_edges=True)\n", " u_plotter.view_xy()\n", " u_plotter.show()\n", "\n", "\n", "#define function space\n", "degreeElements = 1\n", "FS = fem.FunctionSpace(domain, ('Lagrange', degreeElements))\n", "\n", "\n", "#impose Dirichlet boundary conditions\n", "# Create facet to cell connectivity required to determine boundary facets\n", "tdim = domain.topology.dim\n", "fdim = tdim - 1\n", "domain.topology.create_connectivity(fdim, tdim)\n", "boundary_facets = mesh.exterior_facet_indices(domain.topology)\n", "boundary_dofs = fem.locate_dofs_topological(FS, fdim, boundary_facets)\n", "\n", "bc = fem.dirichletbc(ScalarType(0), boundary_dofs, FS)\n", "\n", "#define function u and test function v\n", "u = fem.Function(FS)\n", "v = TestFunction(FS)" ], "metadata": { "id": "pAlwH5zl5qnw" }, "execution_count": 12, "outputs": [] }, { "cell_type": "markdown", "source": [ "The weak formulation of the problem\n", "$$\\int_\\Omega d{\\bf x} \\ (-\\nabla u \\cdot \\nabla v + f(t) v) = 0,$$\n", "where we introduced the time-dependent source term $f(t)$ via the `Constant` object:" ], "metadata": { "id": "BVtNlkrT7Tv8" } }, { "cell_type": "code", "source": [ "# weak formulation of the problem\n", "from petsc4py.PETSc import ScalarType\n", "f = fem.Constant(domain, ScalarType(0.))\n", "Res = -dot(grad(u), grad(v))*dx + f*v*dx\n", "problem = fem.petsc.NonlinearProblem(Res, u, bcs=[bc])\n", "solver = nls.petsc.NewtonSolver(MPI.COMM_WORLD, problem)" ], "metadata": { "id": "jcO03w0l7Kzq" }, "execution_count": 13, "outputs": [] }, { "cell_type": "markdown", "source": [ "To solve the problem multiple times, we just need to update the value of the object `f` and we don't need to redefine the residual `Res`. This is because the residual `Res` is linked to the object `f`. Thus it is important that we update the value of the object `f` rather than creating a new object `f`." ], "metadata": { "id": "Vv5L11ZH7msS" } }, { "cell_type": "code", "source": [ "cmin=0 #lower limit for the colorbar\n", "cmax=0.5 #upper limit for the colorbar\n", "for t in range(0,3):\n", " # update the value of the source term\n", " print(t)\n", " f.value=t\n", " solver.solve(u)\n", " plotScalarFunction(u,[cmin,cmax])" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 1000 }, "id": "usCkviy_7ile", "outputId": "ce3ad886-b6ab-4700-9c4c-965f85d8086e" }, "execution_count": 14, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "0\n" ] }, { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='101...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1012" } } }, { "output_type": "stream", "name": "stdout", "text": [ "1\n" ] }, { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='101...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1016" } } }, { "output_type": "stream", "name": "stdout", "text": [ "2\n" ] }, { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='101...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1020" } } } ] }, { "cell_type": "markdown", "source": [ "Note that if the source term $f(t,{\\bf x})$ also had a spatial dependence, then we can achieve a similar effect with a custom class that is interpolated to the `FunctionSpace`:" ], "metadata": { "id": "kukVlncl8ROL" } }, { "cell_type": "code", "source": [ "class myClass():\n", " def __init__(self, t, a):\n", " self.t = t\n", " self.a = a\n", " def __call__(self, x):\n", " return self.t + self.a*x[0];\n", "fObject = myClass(t,0)\n", "f = fem.Function(FS)\n", "f.interpolate(fObject)\n", "\n", "Res = -dot(grad(u), grad(v))*dx + f*v*dx\n", "problem = fem.petsc.NonlinearProblem(Res, u, bcs=[bc])\n", "solver = nls.petsc.NewtonSolver(MPI.COMM_WORLD, problem)\n", "\n", "cmin=0 #lower limit for the colorbar\n", "cmax=0.5 #upper limit for the colorbar\n", "for t in range(0,3):\n", " # update the value of the source term\n", " print(t)\n", " fObject.t=t\n", " f.interpolate(fObject)\n", " solver.solve(u)\n", " plotScalarFunction(u,[cmin,cmax])" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 1000 }, "id": "Fv6-roKr8EsR", "outputId": "9173b5a2-dd8a-400c-c0d5-de42350db05c" }, "execution_count": 15, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "0\n" ] }, { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='102...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1024" } } }, { "output_type": "stream", "name": "stdout", "text": [ "1\n" ] }, { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='102...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1028" } } }, { "output_type": "stream", "name": "stdout", "text": [ "2\n" ] }, { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='103...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1032" } } } ] }, { "cell_type": "code", "source": [], "metadata": { "id": "SaOEZDp19GZy" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "# General Poisson equation\n", "\n", "This example illustrates how to:\n", "\n", "- Solve a linear partial differential equation with Dirichlet and Neumann boundary conditions;\n", "- Define custom expressions and project them on the `FunctionSpace` \n", "- Calculate the gradient of scalar function and project it on the `VectorFunctionSpace`." ], "metadata": { "id": "3Zdp3hO8-6OW" } }, { "cell_type": "markdown", "source": [ "## Equation and problem definition" ], "metadata": { "id": "KQBZdktL_wFP" } }, { "cell_type": "markdown", "source": [ "The general Poisson equation on a unit disk ($R=1$) with the Dirichlet boundary condition on $\\Gamma_D$ and the Neumann boundary condition on $\\Gamma_N$:\n", "\n", "
\n", " \\begin{array}{r c c l}\n", " \\nabla \\cdot (a \\nabla u) &=& -f & \\text{in } \\Omega,\\\\\n", " u &=& u_D & \\text{on } \\Gamma_D,\\\\\n", " {\\bf n} \\cdot a \\nabla u &=& g & \\text{on } \\Gamma_N,\\\\\n", " \\end{array} \n", "
\n", "where $\\bf n$ is the unit normal vector to the boundary and we introduced functions\n", "
\n", " \\begin{array}{r c l}\n", " a &=& 1-\\frac{1}{2} (x^2 + y^2),\\\\\n", " f &=& 1,\\\\\n", " u_D &=& x,\\\\\n", " g &=& y,\\\\\n", " \\end{array} \n", "
" ], "metadata": { "id": "JWaGpx5J_yyJ" } }, { "cell_type": "markdown", "source": [ "![poisson_general_domain_compressed.png](data:image/png;base64,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VfwqrBp0Jzb0uwF5ofWUdBebpJevrps7Ewc4TWc106xjiVg/9T1smPafYrMZTbkMYWZWIk2n54AGuidvZPkRPPpqBPQeICa4D5A/exrCjidg5Kw30FXy0i0fcg92dxmlklBa6GijkhB5NqC/e5MDbseXgpwcbJn5JVZ/9384fnivugTNZvfccw+efPJJNGrUyJuXrZVtaaCXcVstjZqJzf1NBA29GDn/fRf2revR9OAGjJv8MPZ1HIKVg+7CgTb9JUDGcmL9riV8GWw8600K4GLitYtr9u7FM7Dm+7fFhXVpcXsXXXQRXnrpJdCdVVPFOKCBfgY+MeSVCS3yf5+C3B+/gEum8x2lHFTrfcuxq8tIrD7/DiS06FWksNMS/gycrNiuYoCLr0XcqjlYO3ki4lf/UeyiTNdqSvCbb75Z+WxUrFV9FDmggV7Oc2AKDUfItX9B4NDRyJv6pXKhNacmq/V7x10LsLvThVh33s041KqvFIEMKFLa6XTT5XC15G5mYrUEWFGYn4/4ZXOwXtbg+9fMhUtck0lUsN1777247z5xbDKYIrfkSIz7q9qAfvToUdBvnj7x9LZjtNANN9xQghN0oOExaWlF1Srz5UZ3794d48aNK3GcEX5YYpsg/L6nETLmOuRO/S9s836FRdwtu0tuuk6inY9rPwgb+16H/e3OR35wuADeoePey7lxZknOaJaIwrz049i34nfl0XZ405/qmeGp9M244447lGebtomXw8xydlcb0MPCwhS4X3nlFezatUulhTr33HNLlLehWYS2T663mMed1So9k02U03e/7LZICeeIR19DyJW3IG/6t7AtmAlz2jF02jILHcTDLqF5T2zudSX2dhqO9OjmKjWlWQfNFN8rZnqxSAghDRdpB3fJGnwats/5H1LitxUfQ+UaU33ffffdFY6ELD5ZfymTA9UGdMam33TTTarqCqdc6enpKjcXI+HcRJ/6YcOGYfjw4aoay8cffwwWtasJZG3XuQjw19yB/F8nw7ZoJlwJh9B83yq0EIeb9OgW2CNgp9PN0abdkB8SLhLeJX+MlKtbyjuax5jlRT5EeqeJT/pybJ/3PfavnoO8jJTi281Z36233orbb7+91mZjLR6sj7+UC3ROvatCK1euVCGuDI5hzmz6unumgmL78+fPx8CBA2sMyD35YW3VHuEPPIuQ6/6ipHv+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)" ], "metadata": { "id": "v_MBiOzu_2wQ" } }, { "cell_type": "markdown", "source": [ "### Weak formulation of the problem" ], "metadata": { "id": "B18dXMic_6tn" } }, { "cell_type": "markdown", "source": [ "In FEniCS, we are solving the weak form of the PDE\n", "$$\\int_\\Omega d{\\bf x} \\ (-\\nabla \\cdot (a \\nabla u) - f) \\ v = 0,$$\n", "where $v$ is an arbitrary *test function* that evaluates to $0$ on the boundary points with prescribed values (Dirichlet boundary conditions on $\\Gamma_D$). Using integration by parts, the above equation can be rewritten as \n", "$$\\int_\\Omega d{\\bf x} \\ (a \\nabla u \\cdot \\nabla v - fv) - \\oint_\\Gamma ds \\ ({\\bf n} \\cdot a \\nabla u) v = \\int_\\Omega d{\\bf x} \\ (a \\nabla u \\cdot \\nabla v - fv) - \\oint_\\Gamma ds \\ g v = 0,$$\n", "where we can integrate over the entire boundary $\\Gamma = \\Gamma_D \\bigcup \\Gamma_N$, because $v=0$ on $\\Gamma_D$.\n", "\n", "> The Neumann boundary condition can be recovered naturally from the weak form, and, for that reason, it is also referred to as the *natural boundary condition*. On the other hand, the Dirichlet boundary condition is essential for defining both strong and weak form, and is thus referred to as the *essential boundary condition*." ], "metadata": { "id": "C-gjFwdQABy7" } }, { "cell_type": "markdown", "source": [ "## Implementation" ], "metadata": { "id": "1xbrTh4hAL-W" } }, { "cell_type": "markdown", "source": [ "Following the same steps as in the *basic Poisson equation* example ([click this link](#poissonBasic)), we import relevant libraries, generate mesh, define function space, and define the function $u$ and the test function $v$." ], "metadata": { "id": "TinL5clVAY39" } }, { "cell_type": "code", "source": [ "from dolfinx import *\n", "import gmsh\n", "from dolfinx.io import gmshio\n", "from mpi4py import MPI\n", "from petsc4py.PETSc import ScalarType\n", "from ufl import *\n", "import pyvista\n", "import numpy as np\n", "pyvista.start_xvfb()\n", "\n", "gmsh.initialize()\n", "R = 1. # radius\n", "meshSize = 0.05 # cell size\n", "gdim = 2 # dimensionality of the system\n", "markerId = 1\n", "disk = gmsh.model.occ.addDisk(0, 0, 0, 1, 1)\n", "gmsh.model.occ.synchronize()\n", "gmsh.model.addPhysicalGroup(gdim, [disk], markerId)\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMin\",meshSize)\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMax\",meshSize)\n", "gmsh.model.mesh.generate(gdim)\n", "gmsh_model_rank = 0\n", "mesh_comm = MPI.COMM_WORLD\n", "domain, cell_markers, facet_markers = gmshio.model_to_mesh(gmsh.model, mesh_comm, gmsh_model_rank, gdim=gdim)\n", "gmsh.finalize()\n", "\n", "\n", "def plotScalarFunction(u):\n", " u_topology, u_cell_types, u_geometry = plot.create_vtk_mesh(FS)\n", " u_grid = pyvista.UnstructuredGrid(u_topology, u_cell_types, u_geometry)\n", " u_grid.point_data[\"u\"] = u.x.array.real\n", " u_grid.set_active_scalars(\"u\")\n", " u_plotter = pyvista.Plotter(notebook=True)\n", " u_plotter.add_mesh(u_grid,show_edges=True)\n", " u_plotter.view_xy()\n", " u_plotter.show()\n", "\n", "\n", "#define function space\n", "degreeElements = 1\n", "FS = fem.FunctionSpace(domain, ('Lagrange', degreeElements))\n", "\n", "#define function u and test function v\n", "u = fem.Function(FS)\n", "v = TestFunction(FS)" ], "metadata": { "id": "ThJxYjAW_ZOR" }, "execution_count": 16, "outputs": [] }, { "cell_type": "markdown", "source": [ "To impose Dirichlet boundary conditions ($u_D=x$ on $\\Gamma_D$) on the Function Space `FS`, we have to define a function that returns a boolean value: `True` if the given point $\\bf x$ lies on the Dirichlet boundary $\\Gamma_D$ and `False` otherwise. This is achieved with the function `right_boundary`." ], "metadata": { "id": "nSpyuYM-BJ1V" } }, { "cell_type": "code", "source": [ "def right_boundary(x):\n", " return np.logical_and(np.isclose(np.sqrt(x[0]**2 + x[1]**2), R), x[0]>=0)\n", "dofs_D = fem.locate_dofs_geometrical(FS, right_boundary)\n", "\n", "uD = fem.Function(FS)\n", "uD.interpolate(lambda x: x[0])\n", "bc = fem.dirichletbc(uD, dofs_D)" ], "metadata": { "id": "SoHcMJ8oA0C2" }, "execution_count": 17, "outputs": [] }, { "cell_type": "markdown", "source": [ "To define functions $u_D=x$ and $a=1-\\frac{1}{2} (x^2 + y^2)$, we use the anonymouc lambda function, where `x[0]` and `x[1]` refer to the $x$ and $y$ coordinates, respectively, which is then interpolated to the `FunctionSpace` over the whole domain. The source term, $f=1$, has no spatial dependence and can be prescribed as a number. For the function $g=y$ we use an alternative implementation via a custom class, which is then also interpolated to the `FunctionSpace'." ], "metadata": { "id": "LO0CVsxMBkoq" } }, { "cell_type": "code", "source": [ "a = fem.Function(FS)\n", "a.interpolate(lambda x: 1-0.5*(x[0]**2+x[1]**2))\n", "\n", "f = 1\n", "\n", "class myClass():\n", " def __call__(self, x):\n", " return x[1];\n", "gObject = myClass()\n", "g = fem.Function(FS)\n", "g.interpolate(gObject)" ], "metadata": { "id": "xAAgPy4TBYqk" }, "execution_count": 18, "outputs": [] }, { "cell_type": "markdown", "source": [ "The weak formulation of the problem\n", "$$\\int_\\Omega d{\\bf x} \\ (a \\nabla u \\cdot \\nabla v - fv) - \\oint_\\Gamma ds \\ g v = 0,$$\n", "where `dx` describes the integration over the domain $\\Omega$ and `ds` describes the integration over the boundary $\\Gamma = \\Gamma_D \\bigcup \\Gamma_N$. Note that we can integrate over the entire boundary, because $v=0$ on $\\Gamma_D$." ], "metadata": { "id": "Z1sRF-fyCfvI" } }, { "cell_type": "code", "source": [ "# weak formulation of the problem\n", "Res = a*dot(grad(u), grad(v))*dx - f*v*dx - g*v*ds\n", "problem = fem.petsc.NonlinearProblem(Res, u, bcs=[bc])\n", "solver = nls.petsc.NewtonSolver(MPI.COMM_WORLD, problem)" ], "metadata": { "id": "GRPj8dzPCcNq" }, "execution_count": 19, "outputs": [] }, { "cell_type": "markdown", "source": [ "Next, we solve the problem and plot the solution $u({\\bf x})$." ], "metadata": { "id": "bFLSxGcDCs4u" } }, { "cell_type": "code", "source": [ "# solve the problem\n", "solver.solve(u)\n", "\n", "# plot solution\n", "plotScalarFunction(u)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 327 }, "id": "i5bcNSRlCqKx", "outputId": "a5ccb377-ec8f-4fcd-e7dd-841f6f87d2c2" }, "execution_count": 20, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='103...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1036" } } } ] }, { "cell_type": "markdown", "source": [ "To calculate the function ${\\boldsymbol \\sigma}=a \\nabla u$, we *project* the expression `a*grad(u)` on the `VectorFunctionSpace`. When creating a `VectorFunctionSpace` in FEniCSx, the dimension will be set equal to the geometric\n", "dimension of the finite element mesh. To specify a vector function space with other dimensions one can use the parameter dim, e.g. `V = VectorFunctionSpace(mesh, ('Lagrange', 1), dim=10)` creates a 10 dimensional vector function space with linear Lagrange elements." ], "metadata": { "id": "XZVax3cxC-3J" } }, { "cell_type": "code", "source": [ "degreeElements = 1\n", "VFS = fem.VectorFunctionSpace(domain, ('Lagrange', degreeElements))\n", "sigma_expr = fem.Expression(a*grad(u), VFS.element.interpolation_points())\n", "sigma = fem.Function(VFS)\n", "sigma.interpolate(sigma_expr)\n", "\n", "\n", "def plotVectorFunction(sigma):\n", " topology, cell_types, geometry = plot.create_vtk_mesh(VFS)\n", " values = np.zeros((geometry.shape[0], 3), dtype=np.float64)\n", " values[:, :len(sigma)] = sigma.x.array.real.reshape((geometry.shape[0], len(sigma)))\n", "\n", " # Create a point cloud of glyphs\n", " function_grid = pyvista.UnstructuredGrid(topology, cell_types, geometry)\n", " function_grid[\"sigma\"] = values\n", " glyphs = function_grid.glyph(orient=\"sigma\", factor=0.1)\n", "\n", " # Create a pyvista-grid for the mesh\n", " grid = pyvista.UnstructuredGrid(*plot.create_vtk_mesh(domain, domain.topology.dim))\n", "\n", " # Create plotter\n", " plotter = pyvista.Plotter(notebook=True)\n", " plotter.add_mesh(grid, style=\"wireframe\", color=\"k\")\n", " plotter.add_mesh(glyphs)\n", " plotter.view_xy()\n", " plotter.show()\n", "\n", "plotVectorFunction(sigma)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 327 }, "id": "xRALNFpdCw2-", "outputId": "3fc56285-ff1a-41a7-8c14-16278f842f34" }, "execution_count": 21, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='103...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1040" } } } ] }, { "cell_type": "markdown", "source": [ "# Mixed formulation for the general Poisson equation\n", "\n", "This example is an alternative implementation of the *general Poisson equation* example ([click this link](#poissonGeneral)). It illustrates how to:\n", "\n", "- Solve coupled partial differential equations using `MixedElement`;\n", "- Split the (test)function into (test)functions that correspond to subspaces of the mixed element function space;\n", "- Impose Dirichlet boundary conditions on a subspace of the function space." ], "metadata": { "id": "MeQTOZ8RFSxi" } }, { "cell_type": "markdown", "source": [ "## Equation and problem definition" ], "metadata": { "id": "LvokGMVlFprJ" } }, { "cell_type": "markdown", "source": [ "The mixed formulation of the general Poisson equation on a unit disk ($R=1$) with the Dirichlet boundary condition on $\\Gamma_D$ and the Neumann boundary condition on $\\Gamma_N$:\n", "\n", "
\n", " \\begin{array}{r c c l}\n", " \\nabla \\cdot {\\boldsymbol \\sigma} &=& -f & \\text{in } \\Omega,\\\\\n", " {\\boldsymbol \\sigma} &=& a \\nabla u & \\text{in } \\Omega,\\\\\n", " u &=& u_D & \\text{on } \\Gamma_D,\\\\\n", " {\\bf n} \\cdot {\\boldsymbol \\sigma} &=& g & \\text{on } \\Gamma_N,\\\\\n", " \\end{array} \n", "
\n", "where $\\bf n$ is the unit normal vector to the boundary and we introduced functions\n", "
\n", " \\begin{array}{r c l}\n", " a &=& 1-\\frac{1}{2} (x^2 + y^2),\\\\\n", " f &=& 1,\\\\\n", " u_D &=& x,\\\\\n", " g &=& y.\\\\\n", " \\end{array} \n", "
" ], "metadata": { "id": "JPz0ZhclFtQB" } }, { "cell_type": "markdown", "source": [ "![poisson_general_domain_compressed.png](data:image/png;base64,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VfwqrBp0Jzb0uwF5ofWUdBebpJevrps7Ewc4TWc106xjiVg/9T1smPafYrMZTbkMYWZWIk2n54AGuidvZPkRPPpqBPQeICa4D5A/exrCjidg5Kw30FXy0i0fcg92dxmlklBa6GijkhB5NqC/e5MDbseXgpwcbJn5JVZ/9384fnivugTNZvfccw+efPJJNGrUyJuXrZVtaaCXcVstjZqJzf1NBA29GDn/fRf2revR9OAGjJv8MPZ1HIKVg+7CgTb9JUDGcmL9riV8GWw8600K4GLitYtr9u7FM7Dm+7fFhXVpcXsXXXQRXnrpJdCdVVPFOKCBfgY+MeSVCS3yf5+C3B+/gEum8x2lHFTrfcuxq8tIrD7/DiS06FWksNMS/gycrNiuYoCLr0XcqjlYO3ki4lf/UeyiTNdqSvCbb75Z+WxUrFV9FDmggV7Oc2AKDUfItX9B4NDRyJv6pXKhNacmq/V7x10LsLvThVh33s041KqvFIEMKFLa6XTT5XC15G5mYrUEWFGYn4/4ZXOwXtbg+9fMhUtck0lUsN1777247z5xbDKYIrfkSIz7q9qAfvToUdBvnj7x9LZjtNANN9xQghN0oOExaWlF1Srz5UZ3794d48aNK3GcEX5YYpsg/L6nETLmOuRO/S9s836FRdwtu0tuuk6inY9rPwgb+16H/e3OR35wuADeoePey7lxZknOaJaIwrz049i34nfl0XZ405/qmeGp9M244447lGebtomXw8xydlcb0MPCwhS4X3nlFezatUulhTr33HNLlLehWYS2T663mMed1So9k02U03e/7LZICeeIR19DyJW3IG/6t7AtmAlz2jF02jILHcTDLqF5T2zudSX2dhqO9OjmKjWlWQfNFN8rZnqxSAghDRdpB3fJGnwats/5H1LitxUfQ+UaU33ffffdFY6ELD5ZfymTA9UGdMam33TTTarqCqdc6enpKjcXI+HcRJ/6YcOGYfjw4aoay8cffwwWtasJZG3XuQjw19yB/F8nw7ZoJlwJh9B83yq0EIeb9OgW2CNgp9PN0abdkB8SLhLeJX+MlKtbyjuax5jlRT5EeqeJT/pybJ/3PfavnoO8jJTi281Z36233orbb7+91mZjLR6sj7+UC3ROvatCK1euVCGuDI5hzmz6unumgmL78+fPx8CBA2sMyD35YW3VHuEPPIuQ6/6ipHv+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)" ], "metadata": { "id": "sLB4aCM4F65Y" } }, { "cell_type": "markdown", "source": [ "### Weak formulation of the problem" ], "metadata": { "id": "agYrBpusF_Km" } }, { "cell_type": "markdown", "source": [ "In FEniCSx, we are solving the weak form of coupled PDEs\n", "
\n", " \\begin{array}{l l}\n", " \\int_\\Omega d{\\bf x} \\ (-\\nabla \\cdot {\\boldsymbol \\sigma} -f) v = 0 & \\text{in } \\Omega,\\\\\n", " \\int_\\Omega d{\\bf x} \\ ({\\boldsymbol \\sigma} - a \\nabla u) \\cdot {\\boldsymbol \\tau}=0 & \\text{in } \\Omega,\\\\\n", " \\end{array} \n", "
" ], "metadata": { "id": "HouUpN7BGCFk" } }, { "cell_type": "markdown", "source": [ "where $v$ and ${\\boldsymbol \\tau}$ are arbitrary *test functions*. Here, we assume that the boundary condition $u = u_D$ on $\\Gamma_D$ is the *essential condition* and that the boundary condition ${\\bf n} \\cdot {\\boldsymbol \\sigma} = g$ on $\\Gamma_N$ is the *natural condition*, which can be extracted from the weak form. Thus we impose the restriction $v=0$ on $\\Gamma_D$, but there is no such restriction on ${\\boldsymbol \\tau}$. Using integration by parts, the first equation can be rewritten as \n", "$$\\int_\\Omega d{\\bf x} \\ ({\\boldsymbol \\sigma} \\cdot \\nabla v - fv) - \\oint_\\Gamma ds \\ ({\\bf n} \\cdot {\\boldsymbol \\sigma}) v = \\int_\\Omega d{\\bf x} \\ ({\\boldsymbol \\sigma} \\cdot \\nabla v - fv) - \\oint_\\Gamma ds \\ g v = 0,$$\n", "where we can integrate over the entire boundary $\\Gamma = \\Gamma_D \\bigcup \\Gamma_N$, because $v=0$ on $\\Gamma_D$." ], "metadata": { "id": "oIUsZ_QBGFiy" } }, { "cell_type": "markdown", "source": [ "> Note that it is possible to switch the essential and natural boundary conditions, which is discussed in the FEniCS demo.\n", "" ], "metadata": { "id": "vMlFykxSGI7C" } }, { "cell_type": "markdown", "source": [ "## Implementation" ], "metadata": { "id": "AXes6SErGN4E" } }, { "cell_type": "markdown", "source": [ "We import relevant libraries and generate mesh as was done in the *basic Poisson equation* example ([click this link](#poissonBasic))." ], "metadata": { "id": "7Cl7GbnQGS2j" } }, { "cell_type": "code", "source": [ "from dolfinx import *\n", "import gmsh\n", "from dolfinx.io import gmshio\n", "from mpi4py import MPI\n", "from petsc4py.PETSc import ScalarType\n", "from ufl import *\n", "import pyvista\n", "import numpy as np\n", "pyvista.start_xvfb()\n", "\n", "gmsh.initialize()\n", "R = 1. # radius\n", "meshSize = 0.05 # cell size\n", "gdim = 2 # dimensionality of the system\n", "markerId = 1\n", "disk = gmsh.model.occ.addDisk(0, 0, 0, 1, 1)\n", "gmsh.model.occ.synchronize()\n", "gmsh.model.addPhysicalGroup(gdim, [disk], markerId)\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMin\",meshSize)\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMax\",meshSize)\n", "gmsh.model.mesh.generate(gdim)\n", "gmsh_model_rank = 0\n", "mesh_comm = MPI.COMM_WORLD\n", "domain, cell_markers, facet_markers = gmshio.model_to_mesh(gmsh.model, mesh_comm, gmsh_model_rank, gdim=gdim)\n", "gmsh.finalize()" ], "metadata": { "id": "E9syYzUDEXb_" }, "execution_count": 22, "outputs": [] }, { "cell_type": "markdown", "source": [ "We use `MixedElement` to define the combined function space for both $u$ (scalar) and ${\\boldsymbol \\sigma}$ (vector). First we define `FiniteElement`s that will be used (linear Lagrange elements). Because ${\\boldsymbol \\sigma}$ is a 2D vector field we create `VectorElement's." ], "metadata": { "id": "4_FvAx7jGxXM" } }, { "cell_type": "code", "source": [ "#define function space with mixed finite elements\n", "degreeElements = 1\n", "FE_u = FiniteElement(\"Lagrange\", domain.ufl_cell(), degreeElements)\n", "FE_sigma = VectorElement(\"Lagrange\", domain.ufl_cell(), degreeElements, dim=2)\n", "MFS = fem.FunctionSpace(domain, MixedElement([FE_u, FE_sigma]))" ], "metadata": { "id": "p8Fvy9D8GuBr" }, "execution_count": 23, "outputs": [] }, { "cell_type": "markdown", "source": [ "The (test)functions on this `FunctionSpace` can be defined as usual. However, it is convenient to `split` these (test)functions into (test)functions that correspond to subspaces." ], "metadata": { "id": "QwuyX1Q9HErG" } }, { "cell_type": "code", "source": [ "# define function and split it into u and sigma\n", "mixedFunction = fem.Function(MFS) \n", "u,sigma = split(mixedFunction)\n", "\n", "# define test function and split it into v and tau\n", "tf = TestFunction(MFS)\n", "v,tau = split(tf)" ], "metadata": { "id": "X2jW3R8JHAVX" }, "execution_count": 24, "outputs": [] }, { "cell_type": "markdown", "source": [ "The functions $a$, $f$, and $g$ are implemented in the same way as was done in the *general Poisson equation* example ([click this link](#poissonGeneral))." ], "metadata": { "id": "C1MzIK2IHKmP" } }, { "cell_type": "code", "source": [ "degreeElements = 1\n", "FS = fem.FunctionSpace(domain, ('Lagrange', degreeElements))\n", "a = fem.Function(FS)\n", "a.interpolate(lambda x: 1-0.5*(x[0]**2+x[1]**2))\n", "\n", "f = 1\n", "\n", "class myClass():\n", " def __call__(self, x):\n", " return x[1];\n", "gObject = myClass()\n", "g = fem.Function(FS)\n", "g.interpolate(gObject)" ], "metadata": { "id": "LJGfToTSHHLN" }, "execution_count": 25, "outputs": [] }, { "cell_type": "markdown", "source": [ "The Dirichlet boundary condition $u=u_D=x$ on $\\Gamma_D$ has to be imposed only on the subspace of the entire function space, which can be achieved with `.sub(0)`" ], "metadata": { "id": "Xc060vaTHhXg" } }, { "cell_type": "code", "source": [ "#impose Dirichlet boundary conditions for u\n", "V0, dofs0 = MFS.sub(0).collapse()\n", "def right_boundary(x):\n", " return np.logical_and(np.isclose(np.sqrt(x[0]**2 + x[1]**2), R), x[0]>=0)\n", "boundary_facets = mesh.locate_entities_boundary(domain, domain.topology.dim-1, right_boundary)\n", "dofs_D = fem.locate_dofs_topological((MFS.sub(0),V0), domain.topology.dim-1, boundary_facets)\n", "\n", "uD = fem.Function(V0)\n", "uD.interpolate(lambda x: x[0])\n", "bc = fem.dirichletbc(uD, dofs_D, MFS.sub(0))" ], "metadata": { "id": "I3PB5RItHaGE" }, "execution_count": 26, "outputs": [] }, { "cell_type": "markdown", "source": [ "Next, we write and solve the weak form of the problem. \n", "
\n", " \\begin{array}{l l}\n", " \\int_\\Omega d{\\bf x} \\ ({\\boldsymbol \\sigma} \\cdot \\nabla v - fv) - \\oint_\\Gamma ds \\ g v = 0,\\\\\n", " \\int_\\Omega d{\\bf x} \\ ({\\boldsymbol \\sigma} - a \\nabla u) \\cdot {\\boldsymbol \\tau}=0,\\\\\n", " \\end{array} \n", "
" ], "metadata": { "id": "KvIh-qAmHv2J" } }, { "cell_type": "code", "source": [ "#weak formulation of the problem\n", "Res_1 = (dot(sigma,grad(v)) - f*v)*dx - v*g*ds\n", "Res_2 = (dot(sigma, tau) - dot(a*grad(u), tau))*dx\n", "Res = Res_1 + Res_2\n", "\n", "# solve the problem and store solution in F\n", "problem = fem.petsc.NonlinearProblem(Res, mixedFunction, bcs=[bc])\n", "solver = nls.petsc.NewtonSolver(MPI.COMM_WORLD, problem)\n", "solver.solve(mixedFunction)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "FRL6obz_HrX_", "outputId": "9ae8f53b-788c-427b-dfce-f4d2c6805fdf" }, "execution_count": 27, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(1, True)" ] }, "metadata": {}, "execution_count": 27 } ] }, { "cell_type": "markdown", "source": [ "When ploting the solutions $u$ and ${\\boldsymbol \\sigma}=a \\nabla u$, we have to be careful to use appropriate subspaces." ], "metadata": { "id": "zZ2Vrfn7LDVP" } }, { "cell_type": "code", "source": [ "# plot scalar function u\n", "V0, dofs0 = MFS.sub(0).collapse()\n", "c_topology, c_cell_types, c_geometry = plot.create_vtk_mesh(V0)\n", "c_grid = pyvista.UnstructuredGrid(c_topology, c_cell_types, c_geometry)\n", "c_grid.point_data[\"c\"] = mixedFunction.x.array[dofs0].real\n", "c_grid.set_active_scalars(\"c\")\n", "u_plotter = pyvista.Plotter(notebook=True)\n", "u_plotter.add_mesh(c_grid,show_edges=True)\n", "u_plotter.view_xy()\n", "u_plotter.show()\n", "\n", "\n", "# plot vector function sigma\n", "V1, dofs1 = MFS.sub(1).collapse()\n", "topology, cell_types, geometry = plot.create_vtk_mesh(V1)\n", "values = np.zeros((geometry.shape[0], 3), dtype=np.float64)\n", "values[:, :len(sigma)] = mixedFunction.x.array[dofs1].real.reshape((geometry.shape[0], len(sigma)))\n", "\n", "# Create a point cloud of glyphs\n", "function_grid = pyvista.UnstructuredGrid(topology, cell_types, geometry)\n", "function_grid[\"sigma\"] = values\n", "glyphs = function_grid.glyph(orient=\"sigma\", factor=0.1)\n", "\n", "# Create a pyvista-grid for the mesh\n", "grid = pyvista.UnstructuredGrid(*plot.create_vtk_mesh(domain, domain.topology.dim))\n", "\n", "# Create plotter\n", "plotter = pyvista.Plotter(notebook=True)\n", "plotter.add_mesh(grid, style=\"wireframe\", color=\"k\")\n", "plotter.add_mesh(glyphs)\n", "plotter.view_xy()\n", "plotter.show()" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 632 }, "id": "dAqczLvoLQBg", "outputId": "0c58fac7-eec1-4e9e-d551-b418ef10c02b" }, "execution_count": 28, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='104...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1044" } } }, { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='104...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1048" } } } ] }, { "cell_type": "markdown", "source": [ "# General Poisson equation as the minimization problem\n", "\n", "This example is an alternative implementation of the *general Poisson equation* example ([click this link](#poissonGeneral)). It illustrates how to:\n", "\n", "- Minimize functionals." ], "metadata": { "id": "QPAK9ChUKLTb" } }, { "cell_type": "markdown", "source": [ "## Equation and problem definition" ], "metadata": { "id": "imsQYONTKgXt" } }, { "cell_type": "markdown", "source": [ "Consider a functional \n", "$$E[u] = \\int_\\Omega d{\\bf x} \\left[\\frac{1}{2} a (\\nabla u)^2 - f u \\right] - \\int_{\\Gamma} ds \\ g u,$$\n", "with prescribed values $u=u_D$ on $\\Gamma_D \\subset \\Gamma$, where\n", "
\n", " \\begin{array}{r c l}\n", " a &=& 1-\\frac{1}{2} (x^2 + y^2),\\\\\n", " f &=& 1,\\\\\n", " u_D &=& x,\\\\\n", " g &=& y.\\\\\n", " \\end{array} \n", "
" ], "metadata": { "id": "xDW6BiO0KjnG" } }, { "cell_type": "markdown", "source": [ "![poisson_general_domain_compressed.png](data:image/png;base64,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VfwqrBp0Jzb0uwF5ofWUdBebpJevrps7Ewc4TWc106xjiVg/9T1smPafYrMZTbkMYWZWIk2n54AGuidvZPkRPPpqBPQeICa4D5A/exrCjidg5Kw30FXy0i0fcg92dxmlklBa6GijkhB5NqC/e5MDbseXgpwcbJn5JVZ/9384fnivugTNZvfccw+efPJJNGrUyJuXrZVtaaCXcVstjZqJzf1NBA29GDn/fRf2revR9OAGjJv8MPZ1HIKVg+7CgTb9JUDGcmL9riV8GWw8600K4GLitYtr9u7FM7Dm+7fFhXVpcXsXXXQRXnrpJdCdVVPFOKCBfgY+MeSVCS3yf5+C3B+/gEum8x2lHFTrfcuxq8tIrD7/DiS06FWksNMS/gycrNiuYoCLr0XcqjlYO3ki4lf/UeyiTNdqSvCbb75Z+WxUrFV9FDmggV7Oc2AKDUfItX9B4NDRyJv6pXKhNacmq/V7x10LsLvThVh33s041KqvFIEMKFLa6XTT5XC15G5mYrUEWFGYn4/4ZXOwXtbg+9fMhUtck0lUsN1777247z5xbDKYIrfkSIz7q9qAfvToUdBvnj7x9LZjtNANN9xQghN0oOExaWlF1Srz5UZ3794d48aNK3GcEX5YYpsg/L6nETLmOuRO/S9s836FRdwtu0tuuk6inY9rPwgb+16H/e3OR35wuADeoePey7lxZknOaJaIwrz049i34nfl0XZ405/qmeGp9M244447lGebtomXw8xydlcb0MPCwhS4X3nlFezatUulhTr33HNLlLehWYS2T663mMed1So9k02U03e/7LZICeeIR19DyJW3IG/6t7AtmAlz2jF02jILHcTDLqF5T2zudSX2dhqO9OjmKjWlWQfNFN8rZnqxSAghDRdpB3fJGnwats/5H1LitxUfQ+UaU33ffffdFY6ELD5ZfymTA9UGdMam33TTTarqCqdc6enpKjcXI+HcRJ/6YcOGYfjw4aoay8cffwwWtasJZG3XuQjw19yB/F8nw7ZoJlwJh9B83yq0EIeb9OgW2CNgp9PN0abdkB8SLhLeJX+MlKtbyjuax5jlRT5EeqeJT/pybJ/3PfavnoO8jJTi281Z36233orbb7+91mZjLR6sj7+UC3ROvatCK1euVCGuDI5hzmz6unumgmL78+fPx8CBA2sMyD35YW3VHuEPPIuQ6/6ipHv+nOmw792BiGP7cW7Kf8V//kckNu4qZrmLRGM/DCmx7VEYGCw14gh6R60Nj6XkNsuSjeC2SfWd5O2bsG/Zb9i3/LcS0ptJSzjT4xSdS7bY2FhP9urvXuLAKUBndBkzzripdBIK9/aKfFKKszAi49uZhG/btm0K1EwA4CamcN6yZQtef/1196Ya+WmJbYrQG8YjZOxNKNiwEvl/TEPh+hUwpSWjWfxqJeUH/fkJEpueg70dhshafhBSG7YVSR+hzPFmeREW5bKr2ovVX8yjxpzRgWapoMP1Sk5aClLitopSbY4kgJiNY3s3wymzGTdRwXbxxRcrCT548GAESoippurjwClAX7BggdyQk0UKly1bdtZhfiyOyAw0jz/+OA4fPoxZs2Yp5RtrW7nTVa1btw454hDBKXxtIFNIKIIGXqj+HAfjYFu5CLbFf8C+eyus2cfRavcStN67DLbgCCXdD7fsg/h2A3EstiMyo5oWBdMI1jm9N7LEVxKbmVVFYhPYBbm5yDi0G0m7N+DAuvkSRbYKqft3lLiljHWg9L7uuusUyLWCrQR7qvWHyjBDKU7tN1NJTZsmkkh+e9Lo0aNV3mt6IrGKSkXp+eefx++//w6CmRKda3bWVaOU79mzp2qGCQH4Mlm1alXttY2KMs6+eztsqxajYNUiOPbtgksy3pglvFIV+RPtc3ZkI6Q0bIeEZt1FodcLqQ3aIEvy2uWF1CtmN8Ff9Of0zZSfUlqQzD4qiS2AJqidDhdyjyeLS+oRJbWPbF2G5D0bkXZgl7imZhT3l1/clXX4cmfIKK0qmnzPASXReRNp2mJuuCeeeKJETDmlO6fyNIV5TunL6yrPYzwwp2Vsn9O0Dh06qPLHjGAj0PlCYb3zkSNH1l6Qk1EypbV26aH+wm79G5iwsnDTGhSsWSrfd8ApOe3CUg8jIuUg2uxarI7PDYtGRlRzpbk/1qgjkht1kt/NkBsajTzZxxmBi8DzmOnzp1Jny4eJO9S+ogMsAlaF0uL/5aVB1KqTija6v8ovtd0hhSvzM9OQl5WG3LQkpB/ZK8DejmPxW5CZeAAZ8ueQKLLSREndq1cvXHrppUr3wixFfAY0+Y8DSqJXx+X37duncmb/73//Uzec12B0EU1p1KxzWk9bO/NqT58+XYG9Ovph9DYdSUfgiNuNgs1rlKutI+EgnClJMhe2icQXyc0BiFJL1jqixAtFTlh9VR46TwDPmvAZkvsuJ6Ih+GLIC4mSLDmhqjKNwxIIhzjwMMxW9H5Iyzgu7wDOBFxwiJS2SUELp4TfOgoLVMhnQW6maMBTZW2dhJzURGSnHJG/BLWN6ZI9teOleUpgM5sLX+p0S6XJVPufl+aSf3+fskb3Vnc4FaejDN/sbqLDzMSJE3Hw4EHMnDlT6QKoge/du7f7kDr3Sb96/gWeP1yN3SH13gl2rukLd26VnPT74RRPPKcot8x52YjMzUK95DhB+fDuAAAB/0lEQVQFWCjFl0hqAa77u90aJEDnXxHQWYIotcCBccu3IVskNIFul+Pz5SXglEQgjkKbfJZcqp3uJlBhRgBz+UYwM6MQcwwS5Do89HRcM8b2apPo9EemxKbpzHPaduONN6oKGRdeeKFar9NphhJdU9kccAkYnceOipRPhiPxMBySHMMhPveU+sxs68rOgis3G668XLikGgmBzDl70adMBmRKkJBvR88NSSivPg2z+FJhxpcv/+iZ1qZNG2XTpp85l3YEeVlFLsvuvd5qFA5Ui0TPErvpihUrwLLHniDnoP/yl7+oND9LlixRGWOZZ1vT6Tlgkhcha8DzL6B73xIHEtwK7DkEek4R4BXw5Tt/E/jiitswLx9vbduHAirzZCpvEctAWLOWCBbFKMM9mcmXnoz8I8CpQOM2bfIqwe4a/aNagL5x40ZlTmM4YWkaOnQo+vTpgzVr1qjccTrUsDSHKv6bpjyCtjwKkQOkCp2mOswBqmK9Tl9KXXPmj+vUqdMpbXN6eId4QZGoeefUUJPmgOZA9XLAq0BnFBprr9Emn5SUhH/961+g9r000TMuOjpalavV08PS3NG/NQe8zwGvTt1pF6etnBKda3Pa5un1VpqaNGkClnqiOUaT5oDmQPVzoNq07tXfdX0FzQHNgYpywKtT94peVB+nOaA54FsO/D8pU+BrSHo02gAAAABJRU5ErkJggg==)" ], "metadata": { "id": "uchyBOyIKon1" } }, { "cell_type": "markdown", "source": [ "A small variation of the function $u+\\delta u$ with $\\delta u=0$ on $\\Gamma_D$ results in the variation of the functional $E[u+\\delta u] = E[u]+\\delta E$ where \n", "$$\\delta E = \\int_\\Omega d{\\bf x} \\left[a \\nabla u \\cdot \\nabla \\delta u - f \\delta u \\right] - \\int_{\\Gamma} ds \\ g \\delta u.$$\n", "\n", "We are searching for the function $u$ that minimizes the functional $E[u]$. In this case, the variation $\\delta E$ has to vanish\n", "
\n", " \\begin{array}{r c l}\n", " 0 & =& \\int_\\Omega d{\\bf x} \\left[a \\nabla u \\cdot \\nabla \\delta u - f \\delta u \\right] - \\int_{\\Gamma} ds \\ g \\delta u,\\\\\n", " 0 & =& \\int_\\Omega d{\\bf x} \\left[- \\nabla \\cdot (a \\nabla u) - f \\right] \\delta u + \\int_{\\Gamma} ds \\ ({\\bf n} \\cdot a \\nabla u -g) \\delta u, \n", " \\end{array} \n", "
\n", "where $\\bf n$ is the unit normal vector to the boundary and we used the integration by parts in the second line. Since the variation $\\delta u$ is arbitrary, the function $u$ that minimizes the functional $E[u]$ has to satisfy the equations \n", "
\n", " \\begin{array}{r c c l}\n", " \\nabla \\cdot (a \\nabla u) &=& -f & \\text{in } \\Omega,\\\\\n", " u &=& u_D & \\text{on } \\Gamma_D,\\\\\n", " {\\bf n} \\cdot a \\nabla u &=& g & \\text{on } \\Gamma_N.\\\\\n", " \\end{array} \n", "
" ], "metadata": { "id": "o1fJ-_KOMm7f" } }, { "cell_type": "markdown", "source": [ "These equations are identical to the ones discussed in the *general Poisson equation* example ([click this link](#poissonGeneral)).\n", "\n", "> Note: The variation $\\delta u$ plays a similar role as the test function $v$ in the weak formulation of the general Poisson equation.\n", "" ], "metadata": { "id": "VF-lcFraMtmo" } }, { "cell_type": "markdown", "source": [ "## Implementation" ], "metadata": { "id": "ySykhHNCM3NQ" } }, { "cell_type": "markdown", "source": [ "Following the same steps as in the *general Poisson equation* example ([click this link](#poissonGeneral)), we import relevant libraries, generate mesh, define function space, the function $u$, the test function $v$, and the functions $a$, $f$, and $g$, and impose Dirichlet boundary conditions $u=u_D$." ], "metadata": { "id": "o4pXseOHM6PU" } }, { "cell_type": "code", "source": [ "from dolfinx import *\n", "import gmsh\n", "from dolfinx.io import gmshio\n", "from mpi4py import MPI\n", "from petsc4py.PETSc import ScalarType\n", "from ufl import *\n", "import pyvista\n", "import numpy as np\n", "pyvista.start_xvfb()\n", "\n", "gmsh.initialize()\n", "R = 1. # radius\n", "meshSize = 0.05 # cell size\n", "gdim = 2 # dimensionality of the system\n", "markerId = 1\n", "disk = gmsh.model.occ.addDisk(0, 0, 0, 1, 1)\n", "gmsh.model.occ.synchronize()\n", "gmsh.model.addPhysicalGroup(gdim, [disk], markerId)\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMin\",meshSize)\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMax\",meshSize)\n", "gmsh.model.mesh.generate(gdim)\n", "gmsh_model_rank = 0\n", "mesh_comm = MPI.COMM_WORLD\n", "domain, cell_markers, facet_markers = gmshio.model_to_mesh(gmsh.model, mesh_comm, gmsh_model_rank, gdim=gdim)\n", "gmsh.finalize()\n", "\n", "\n", "def plotScalarFunction(u):\n", " u_topology, u_cell_types, u_geometry = plot.create_vtk_mesh(FS)\n", " u_grid = pyvista.UnstructuredGrid(u_topology, u_cell_types, u_geometry)\n", " u_grid.point_data[\"u\"] = u.x.array.real\n", " u_grid.set_active_scalars(\"u\")\n", " u_plotter = pyvista.Plotter(notebook=True)\n", " u_plotter.add_mesh(u_grid,show_edges=True)\n", " u_plotter.view_xy()\n", " u_plotter.show()\n", "\n", "def plotVectorFunction(sigma):\n", " topology, cell_types, geometry = plot.create_vtk_mesh(VFS)\n", " values = np.zeros((geometry.shape[0], 3), dtype=np.float64)\n", " values[:, :len(sigma)] = sigma.x.array.real.reshape((geometry.shape[0], len(sigma)))\n", " # Create a point cloud of glyphs\n", " function_grid = pyvista.UnstructuredGrid(topology, cell_types, geometry)\n", " function_grid[\"sigma\"] = values\n", " glyphs = function_grid.glyph(orient=\"sigma\", factor=0.1)\n", " # Create a pyvista-grid for the mesh\n", " grid = pyvista.UnstructuredGrid(*plot.create_vtk_mesh(domain, domain.topology.dim))\n", " # Create plotter\n", " plotter = pyvista.Plotter(notebook=True)\n", " plotter.add_mesh(grid, style=\"wireframe\", color=\"k\")\n", " plotter.add_mesh(glyphs)\n", " plotter.view_xy()\n", " plotter.show()\n", "\n", "\n", "#define function space\n", "degreeElements = 1\n", "FS = fem.FunctionSpace(domain, ('Lagrange', degreeElements))\n", "\n", "#define function u and test function v\n", "u = fem.Function(FS)\n", "v = TestFunction(FS)\n", "\n", "def right_boundary(x):\n", " return np.logical_and(np.isclose(np.sqrt(x[0]**2 + x[1]**2), R), x[0]>=0)\n", "dofs_D = fem.locate_dofs_geometrical(FS, right_boundary)\n", "\n", "uD = fem.Function(FS)\n", "uD.interpolate(lambda x: x[0])\n", "bc = fem.dirichletbc(uD, dofs_D)\n", "\n", "\n", "\n", "a = fem.Function(FS)\n", "a.interpolate(lambda x: 1-0.5*(x[0]**2+x[1]**2))\n", "\n", "f = 1\n", "\n", "class myClass():\n", " def __call__(self, x):\n", " return x[1];\n", "gObject = myClass()\n", "g = fem.Function(FS)\n", "g.interpolate(gObject)" ], "metadata": { "id": "U0JrXwM4KmR8" }, "execution_count": 29, "outputs": [] }, { "cell_type": "markdown", "source": [ "Next we define the energy functional\n", "$$E[u] = \\int_\\Omega d{\\bf x} \\left[\\frac{1}{2} a (\\nabla u)^2 - f u \\right] - \\int_{\\Gamma} ds \\ g u.$$" ], "metadata": { "id": "K_uFZb6tNhgk" } }, { "cell_type": "code", "source": [ "# functional\n", "E = (1/2*a*dot(grad(u),grad(u))-f*u)*dx - g*u*ds" ], "metadata": { "id": "z_PhEKu4Nem3" }, "execution_count": 30, "outputs": [] }, { "cell_type": "markdown", "source": [ "Here `dx` describes the integration over the domain $\\Omega$ and `ds` describes the integration over the boundary $\\Gamma = \\Gamma_D \\bigcup \\Gamma_N$. Note that we integrated over the entire boundary, because we will use the fact that the variation $\\delta u=v=0$ on $\\Gamma_D$." ], "metadata": { "id": "TbFVrQ5zNolR" } }, { "cell_type": "markdown", "source": [ "To calculate the variation $\\delta E$, we use the `derivate` function, where the first argument is the functional $E[u]$, the second argument is the function $u$, and the third argument is the variation $v=\\delta u$. Note that here we use the arbitrary *test function* $v$ in the third argument, which is used by FEniCS to solve the minimization problem." ], "metadata": { "id": "x1veTEkZN5NV" } }, { "cell_type": "code", "source": [ "# solve the problem\n", "Res = derivative(E, u, v)\n", "problem = fem.petsc.NonlinearProblem(Res, u, bcs=[bc])\n", "solver = nls.petsc.NewtonSolver(MPI.COMM_WORLD, problem)\n", "solver.solve(u)\n", "\n", "# plot solution\n", "plotScalarFunction(u)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 327 }, "id": "qw2PHy19Njyh", "outputId": "0adc93d5-cd0c-48c0-d247-2781cd45b466" }, "execution_count": 31, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='105...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1052" } } } ] }, { "cell_type": "markdown", "source": [ "We plot the solution $u$ and calculate ${\\boldsymbol \\sigma}=a \\nabla u$ and $\\nabla \\cdot {\\boldsymbol \\sigma}=\\nabla \\cdot (a \\nabla u)$\n", "as was done in the *general Poisson equation* example ([click this link](#poissonGeneral))." ], "metadata": { "id": "Ugv2ro7-OOTA" } }, { "cell_type": "code", "source": [ "degreeElements = 1\n", "VFS = fem.VectorFunctionSpace(domain, ('Lagrange', degreeElements))\n", "sigma_expr = fem.Expression(a*grad(u), VFS.element.interpolation_points())\n", "sigma = fem.Function(VFS)\n", "sigma.interpolate(sigma_expr)\n", "\n", "plotVectorFunction(sigma)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 327 }, "id": "KwshmkalOGCO", "outputId": "6a971593-1476-4b59-add9-3360e3abc6ee" }, "execution_count": 32, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, color_mappers=[LinearColorMapper(id='105...], sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1056" } } } ] }, { "cell_type": "markdown", "source": [ "# Linear deformation of elastic material with a circular hole using clamped-free boundary conditions\n", "\n", "This example illustrates how to:\n", "\n", "- Subtract domains, when generating meshes;\n", "- Use tensors and tensor operations;\n", "- Impose Dirichlet boundary conditions on subspaces of the function space;\n", "- Export solution into an XDMF file for visualization in ParaView." ], "metadata": { "id": "vhvQQ3nSTTuh" } }, { "cell_type": "markdown", "source": [ "## Equation and problem definition" ], "metadata": { "id": "3PGTGxLiTqWw" } }, { "cell_type": "markdown", "source": [ "We consider linear deformation of a 2D elastic material with a circular hole by imposing clamped boundary conditions on the left ($\\Gamma_l$) and right ($\\Gamma_r$) boundaries and traction-free boundary conditions (i.e., free from external loads) on all other boundaries ($\\Gamma_t$, $\\Gamma_b$, $\\Gamma_h$)." ], "metadata": { "id": "Nwozjn-gTvwe" } }, { "cell_type": "markdown", "source": [ "![elasticity_clamped_domain.png](data:image/png;base64,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)" ], "metadata": { "id": "pUikOs0OTz0M" } }, { "cell_type": "markdown", "source": [ "Linear deformation of the elastic material can be obtained by solving the force-balance equation\n", "$$\\partial_j \\sigma_{ij} = 0 \\text{ in } \\Omega,$$\n", "where $\\sigma_{ij}$ is the stress tensor, where $i,j\\in\\{x,y\\}$ and the summation over repeated indices is implied. The constitutive equations for a linear elastic material are \n", "$$\\sigma_{ij} = 2 \\mu \\epsilon_{ij} + \\lambda \\epsilon_{kk} \\delta_{ij},$$\n", "where $\\lambda$ and $\\mu$ are 2D Lamé constants that can be expressed in terms of the 2D Young's modulus $E$ and the Poisson's ratio $\\nu$ as $\\mu=E/[2(1+\\nu)]$ and $\\lambda = E \\nu/(1-\\nu^2)$. In this example, we use $E=1$ and $\\nu=0.4$. We also introduced the strain tensor\n", "$$\\epsilon_{ij} = \\frac{1}{2} \\left(\\partial_i u_j + \\partial_j u_i\\right),$$\n", "where $u_i$ are compontents of displacements $\\bf u$." ], "metadata": { "id": "5wNO8FcST29F" } }, { "cell_type": "markdown", "source": [ "The left and right boundaries are clamped, i.e., this is where we prescribe displacements. In this example, we have $u_x^D = -\\Delta/2$ and $u_y^D=0$ on the left boundary ($\\Gamma_l$) and $u_x^D = +\\Delta/2$ and $u_y^D=0$ on the right boundary ($\\Gamma_r$). Here we use $\\Delta=0.2 L$ to exaggerate the deformation. All other boundaries ($\\Gamma_t$, $\\Gamma_b$, $\\Gamma_h$) are traction-free with $\\sigma_{ij} n_j = 0$, where $n_j$ is the unit normal vector to the boundary. " ], "metadata": { "id": "CnTQNz71T83s" } }, { "cell_type": "markdown", "source": [ "### Energy minimization formulation of the problem" ], "metadata": { "id": "kEg_9jM6T_-i" } }, { "cell_type": "markdown", "source": [ "Rather than solving the PDE equations described in the previous section we reformulate the problem as the minimization of the elastic energy\n", "$$E_{el}[u_i]=\\int_\\Omega d{\\bf x} \\ \\frac{1}{2} \\sigma_{ij} \\epsilon_{ij},$$\n", "with prescribed displacements on the clamped boundaries." ], "metadata": { "id": "sdzpOBOSUDDK" } }, { "cell_type": "markdown", "source": [ "## Implementation" ], "metadata": { "id": "9xw6wjkUUFfv" } }, { "cell_type": "markdown", "source": [ "Before we can use FEniCS we need to import relevant modules." ], "metadata": { "id": "LK7zkKtZUJRQ" } }, { "cell_type": "code", "source": [ "from dolfinx import *\n", "import gmsh\n", "from dolfinx.io import gmshio\n", "from mpi4py import MPI\n", "from petsc4py.PETSc import ScalarType\n", "from ufl import *\n", "import pyvista\n", "pyvista.start_xvfb()" ], "metadata": { "id": "YFCVvKbYUM6d" }, "execution_count": 33, "outputs": [] }, { "cell_type": "markdown", "source": [ "To define a rectangular domain with a circular hole we subtract the two domains and generate a triangular mesh." ], "metadata": { "id": "8J3-35yGUSdL" } }, { "cell_type": "code", "source": [ "# Create rectangular mesh with circular hole\n", "L = 1\n", "R = 0.2\n", "gdim = 2\n", "meshSize = 0.02 # mesh resolution\n", "\n", "gmsh.initialize()\n", "markerId = 1\n", "outerBox = gmsh.model.occ.addRectangle(-L/2, -L/2, 0, L, L,0)\n", "innerHole = gmsh.model.occ.addDisk(0, 0, 0, R, R)\n", "membrane = gmsh.model.occ.cut([(2, outerBox)], [(2, innerHole)])\n", "gmsh.model.occ.synchronize()\n", "volumes = gmsh.model.getEntities(dim=2)\n", "assert(volumes == membrane[0])\n", "membrane_marker = 11\n", "gmsh.model.addPhysicalGroup(volumes[0][0], [volumes[0][1]], membrane_marker)\n", "\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMin\",meshSize)\n", "gmsh.option.setNumber(\"Mesh.CharacteristicLengthMax\",meshSize)\n", "gmsh.model.mesh.generate(gdim)\n", "gmsh_model_rank = 0\n", "mesh_comm = MPI.COMM_WORLD\n", "domain, cell_markers, facet_markers = gmshio.model_to_mesh(gmsh.model, mesh_comm, gmsh_model_rank, gdim=gdim)\n", "gmsh.finalize()\n", "\n", "print(pyvista.global_theme.jupyter_backend)\n", "tdim = domain.topology.dim\n", "topology, cell_types, geometry = plot.create_vtk_mesh(domain, tdim)\n", "grid = pyvista.UnstructuredGrid(topology, cell_types, geometry)\n", "plotter = pyvista.Plotter(notebook=True)\n", "plotter.add_mesh(grid, show_edges=True)\n", "plotter.view_xy()\n", "plotter.show()" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 345 }, "id": "FW99p_N4UZ58", "outputId": "ac2db277-37be-48ab-d441-6b891fd6b513" }, "execution_count": 34, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "panel\n" ] }, { "output_type": "display_data", "data": { "application/javascript": [ "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, js_modules, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", " if (js_modules == null) js_modules = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls.length === 0 && js_modules.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error() {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (var i = 0; i < css_urls.length; i++) {\n", " var url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " var skip = [];\n", " if (window.requirejs) {\n", " window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n", " require([\"vtk\"], function() {\n", "\ton_load()\n", " })\n", " require([\"gridstack\"], function(GridStack) {\n", "\twindow.GridStack = GridStack\n", "\ton_load()\n", " })\n", " require([\"notyf\"], function() {\n", "\ton_load()\n", " })\n", " root._bokeh_is_loading = css_urls.length + 3;\n", " } else {\n", " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n", " } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n", " var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n", " for (var i = 0; i < urls.length; i++) {\n", " skip.push(urls[i])\n", " }\n", " } for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " for (var i = 0; i < js_modules.length; i++) {\n", " var url = js_modules[i];\n", " if (skip.indexOf(url) >= 0) {\n", "\tif (!window.requirejs) {\n", "\t on_load();\n", "\t}\n", "\tcontinue;\n", " }\n", " var element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error;\n", " element.async = false;\n", " element.src = url;\n", " element.type = \"module\";\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " if (!js_urls.length && !js_modules.length) {\n", " on_load()\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n", " var js_modules = [];\n", " var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n", " var inline_js = [ function(Bokeh) {\n", " inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n", " }, function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", "function(Bokeh) {} // ensure no trailing comma for IE\n", " ];\n", "\n", " function run_inline_js() {\n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " }\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, js_modules, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'vtk': 'https://cdn.jsdelivr.net/npm/vtk.js@20.0.1/vtk', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@4.2.5/dist/gridstack-h5', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'vtk': {'exports': 'vtk'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"vtk\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 3;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length;\n } if (((window['vtk'] !== undefined) && (!(window['vtk'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/gridstack/gridstack@4.2.5/dist/gridstack-h5.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/0.14.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) >= 0) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/bundled/abstractvtkplot/vtk.js@20.0.1/vtk.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\", \"https://unpkg.com/@holoviz/panel@0.14.3/dist/panel.min.js\"];\n var js_modules = [];\n var css_urls = [\"https://cdn.holoviz.org/panel/0.14.3/dist/css/markdown.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/dataframe.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/card.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/widgets.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/debugger.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/alerts.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/json.css\", \"https://cdn.holoviz.org/panel/0.14.3/dist/css/loading.css\"];\n var inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n .bk.pn-loading.arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n }\\n \");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, js_modules, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {} }, { "output_type": "display_data", "data": { "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/javascript": [ "\n", "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", "}\n", "\n", "\n", " function JupyterCommManager() {\n", " }\n", "\n", " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " comm_manager.register_target(comm_id, function(comm) {\n", " comm.on_msg(msg_handler);\n", " });\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", " comm.onMsg = msg_handler;\n", " });\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " console.log(message)\n", " var content = {data: message.data, comm_id};\n", " var buffers = []\n", " for (var buffer of message.buffers || []) {\n", " buffers.push(new DataView(buffer))\n", " }\n", " var metadata = message.metadata || {};\n", " var msg = {content, buffers, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " })\n", " }\n", " }\n", "\n", " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", " if (comm_id in window.PyViz.comms) {\n", " return window.PyViz.comms[comm_id];\n", " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", " if (msg_handler) {\n", " comm.on_msg(msg_handler);\n", " }\n", " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", " comm.open();\n", " if (msg_handler) {\n", " comm.onMsg = msg_handler;\n", " }\n", " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", " comm_promise.then((comm) => {\n", " window.PyViz.comms[comm_id] = comm;\n", " if (msg_handler) {\n", " var messages = comm.messages[Symbol.asyncIterator]();\n", " function processIteratorResult(result) {\n", " var message = result.value;\n", " var content = {data: message.data};\n", " var metadata = message.metadata || {comm_id};\n", " var msg = {content, metadata}\n", " msg_handler(msg);\n", " return messages.next().then(processIteratorResult);\n", " }\n", " return messages.next().then(processIteratorResult);\n", " }\n", " }) \n", " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", " return comm_promise.then((comm) => {\n", " comm.send(data, metadata, buffers, disposeOnDone);\n", " });\n", " };\n", " var comm = {\n", " send: sendClosure\n", " };\n", " }\n", " window.PyViz.comms[comm_id] = comm;\n", " return comm;\n", " }\n", " window.PyViz.comm_manager = new JupyterCommManager();\n", " \n", "\n", "\n", "var JS_MIME_TYPE = 'application/javascript';\n", "var HTML_MIME_TYPE = 'text/html';\n", "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", "var CLASS_NAME = 'output';\n", "\n", "/**\n", " * Render data to the DOM node\n", " */\n", "function render(props, node) {\n", " var div = document.createElement(\"div\");\n", " var script = document.createElement(\"script\");\n", " node.appendChild(div);\n", " node.appendChild(script);\n", "}\n", "\n", "/**\n", " * Handle when a new output is added\n", " */\n", "function handle_add_output(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", " if (id !== undefined) {\n", " var nchildren = toinsert.length;\n", " var html_node = toinsert[nchildren-1].children[0];\n", " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", " var scripts = [];\n", " var nodelist = html_node.querySelectorAll(\"script\");\n", " for (var i in nodelist) {\n", " if (nodelist.hasOwnProperty(i)) {\n", " scripts.push(nodelist[i])\n", " }\n", " }\n", "\n", " scripts.forEach( function (oldScript) {\n", " var newScript = document.createElement(\"script\");\n", " var attrs = [];\n", " var nodemap = oldScript.attributes;\n", " for (var j in nodemap) {\n", " if (nodemap.hasOwnProperty(j)) {\n", " attrs.push(nodemap[j])\n", " }\n", " }\n", " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", " oldScript.parentNode.replaceChild(newScript, oldScript);\n", " });\n", " if (JS_MIME_TYPE in output.data) {\n", " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", " }\n", " output_area._hv_plot_id = id;\n", " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", " window.PyViz.plot_index[id] = Bokeh.index[id];\n", " } else {\n", " window.PyViz.plot_index[id] = null;\n", " }\n", " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", "}\n", "\n", "/**\n", " * Handle when an output is cleared or removed\n", " */\n", "function handle_clear_output(event, handle) {\n", " var id = handle.cell.output_area._hv_plot_id;\n", " var server_id = handle.cell.output_area._bokeh_server_id;\n", " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", " if (server_id !== null) {\n", " comm.send({event_type: 'server_delete', 'id': server_id});\n", " return;\n", " } else if (comm !== null) {\n", " comm.send({event_type: 'delete', 'id': id});\n", " }\n", " delete PyViz.plot_index[id];\n", " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", " var doc = window.Bokeh.index[id].model.document\n", " doc.clear();\n", " const i = window.Bokeh.documents.indexOf(doc);\n", " if (i > -1) {\n", " window.Bokeh.documents.splice(i, 1);\n", " }\n", " }\n", "}\n", "\n", "/**\n", " * Handle kernel restart event\n", " */\n", "function handle_kernel_cleanup(event, handle) {\n", " delete PyViz.comms[\"hv-extension-comm\"];\n", " window.PyViz.plot_index = {}\n", "}\n", "\n", "/**\n", " * Handle update_display_data messages\n", " */\n", "function handle_update_output(event, handle) {\n", " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", " handle_add_output(event, handle)\n", "}\n", "\n", "function register_renderer(events, OutputArea) {\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[0]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " events.on('output_added.OutputArea', handle_add_output);\n", " events.on('output_updated.OutputArea', handle_update_output);\n", " events.on('clear_output.CodeCell', handle_clear_output);\n", " events.on('delete.Cell', handle_clear_output);\n", " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", "\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " safe: true,\n", " index: 0\n", " });\n", "}\n", "\n", "if (window.Jupyter !== undefined) {\n", " try {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " } catch(err) {\n", " }\n", "}\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "" ] }, "metadata": {} }, { "output_type": "display_data", "data": {}, "metadata": {} }, { "output_type": "display_data", "data": { "text/html": [ "
\n", "
\n", "
\n", "" ], "application/vnd.holoviews_exec.v0+json": "", "text/plain": [ "VTKRenderWindowSynchronized(vtkXOpenGLRenderWindow, sizing_mode='stretch_width')" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1059" } } } ] }, { "cell_type": "markdown", "source": [ "Define elastic constants and the displacements of the two clamped ends" ], "metadata": { "id": "D1Qpwm3RUkuo" } }, { "cell_type": "code", "source": [ "# elastic constants\n", "E = 1\n", "nu = 0.4\n", "mu = E/2/(1+nu)\n", "Lambda = E*nu/(1-nu*nu)\n", "\n", "# displacement of the clamped ends\n", "Delta = 0.2*L" ], "metadata": { "id": "MlrbocG6UrEx" }, "execution_count": 35, "outputs": [] }, { "cell_type": "markdown", "source": [ "Define the vector function space, the function for displacements ${\\bf u}\\equiv (u_x, u_y)$ and the test function $\\bf v$." ], "metadata": { "id": "EN-ZAgf7Ut7D" } }, { "cell_type": "code", "source": [ "#define vector function space, function u, and test function v\n", "degreeElements = 1\n", "VFS = fem.VectorFunctionSpace(domain, ('Lagrange', degreeElements))\n", "u = fem.Function(VFS)\n", "v = TestFunction(VFS)" ], "metadata": { "id": "BV6gBk6HUzWg" }, "execution_count": 36, "outputs": [] }, { "cell_type": "markdown", "source": [ "To impose the Dirichlet boundary conditions for displacements of clamped boundaries, we need to define functions `left_boundary` and `right_boundary` that return `True` for points that are on the left and right boundaries, respectively. Constant displacement vectors $(u_x,u_y)$ on these boundaries are prescribed with the `ScalarType` function." ], "metadata": { "id": "u226lzBRU2X0" } }, { "cell_type": "code", "source": [ "#impose clamped boundary conditions\n", "def left_boundary(x):\n", " return np.isclose(x[0],-L/2);\n", "def right_boundary(x):\n", " return np.isclose(x[0],+L/2);\n", "\n", "fdim = domain.topology.dim - 1\n", "boundary_facets_left = mesh.locate_entities_boundary(domain, fdim, left_boundary)\n", "dofs_left = fem.locate_dofs_topological(VFS, fdim, boundary_facets_left)\n", "u_left = ScalarType((-Delta/2, 0))\n", "bc_left = fem.dirichletbc(u_left, dofs_left, VFS)\n", "\n", "boundary_facets_right = mesh.locate_entities_boundary(domain, fdim, right_boundary)\n", "dofs_right = fem.locate_dofs_topological(VFS, fdim, boundary_facets_right)\n", "u_right = ScalarType((+Delta/2, 0))\n", "bc_right = fem.dirichletbc(u_right, dofs_right, VFS)\n", "\n", "bc = [bc_left, bc_right]" ], "metadata": { "id": "wqSfSrmMVAET" }, "execution_count": 37, "outputs": [] }, { "cell_type": "markdown", "source": [ "We define the strain tensor $\\epsilon_{ij} = \\frac{1}{2} \\left(\\partial_i u_j + \\partial_j u_i\\right)$ as `sym(grad(u))`, where the `sym` function returns $sym(M_{ij})=\\frac{1}{2} (M_{ij}+M_{ji})$ and the `grad(u)` expression results in $\\partial_i u_j$. We also define the constitutive equations $\\sigma_{ij} = 2 \\mu \\epsilon_{ij} + \\lambda \\epsilon_{kk} \\delta_{ij}$." ], "metadata": { "id": "JosTtu8hVRyI" } }, { "cell_type": "code", "source": [ "tdim=domain.topology.dim\n", "# define strain and stress\n", "def epsilon(u):\n", " return sym(grad(u))\n", "def sigma(u):\n", " return 2*mu*epsilon(u) + Lambda*tr(epsilon(u))*Identity(tdim)" ], "metadata": { "id": "_Hl60flLVaL0" }, "execution_count": 38, "outputs": [] }, { "cell_type": "markdown", "source": [ "To calculate the elastic energy $E_{el}[u_i]=\\int_\\Omega d{\\bf x} \\ \\frac{1}{2} \\sigma_{ij} \\epsilon_{ij}$ we use the inner product of tensors. Then we minimize the elastic energy and impose Dirichlet boundary conditions on the two clamped ends." ], "metadata": { "id": "ycDCuh6_VjzZ" } }, { "cell_type": "code", "source": [ "# elastic energy\n", "Energy = 1/2*inner(sigma(u),epsilon(u))*dx\n", "\n", "# minimize elastic energy\n", "Res = derivative(Energy, u, v)\n", "# solve the problem\n", "problem = fem.petsc.NonlinearProblem(Res, u, bcs=bc)\n", "solver = nls.petsc.NewtonSolver(MPI.COMM_WORLD, problem)\n", "solver.solve(u)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "sT7fkiYmVqdm", "outputId": "6a8a2489-f056-4428-c38a-ae82bf5248c2" }, "execution_count": 39, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(1, True)" ] }, "metadata": {}, "execution_count": 39 } ] }, { "cell_type": "markdown", "source": [ "To evaluate the value of the elastic energy, we can use the `assemble_scalar` function" ], "metadata": { "id": "gSu3u_28VxZm" } }, { "cell_type": "code", "source": [ "# calculate elastic energy\n", "print(\"Energy = \", fem.assemble_scalar(fem.form(Energy)))" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "F6UDckrNV0Z3", "outputId": "4c3be376-6791-4d15-ad13-08de400121fd" }, "execution_count": 40, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Energy = 0.014412390517361618\n" ] } ] }, { "cell_type": "markdown", "source": [ "In mechanics, it is common to analyze stresses by visualization of the von Mises stress, which is defined as \n", "$\\sigma_\\text{vM} = \\sqrt{(3/2) \\hat \\sigma_{ij} \\hat \\sigma_{ij}}$, where $\\hat \\sigma_{ij}=\\sigma_{ij}-(1/d) \\sigma_{kk} \\delta_{ij}$ is the deviatoric stress." ], "metadata": { "id": "fhhKJj6KV7Ro" } }, { "cell_type": "code", "source": [ "# calculate and export von Mises stress\n", "V_von_mises = fem.FunctionSpace(domain, ('Lagrange', 1))\n", "devStress = sigma(u) - (1./tdim)*tr(sigma(u))*Identity(tdim) # deviatoric stress\n", "von_Mises = sqrt(3./2*inner(devStress, devStress))\n", "stress_expr = fem.Expression(von_Mises, V_von_mises.element.interpolation_points())\n", "stresses = fem.Function(V_von_mises)\n", "stresses.interpolate(stress_expr)" ], "metadata": { "id": "idLHdCzNV-ZH" }, "execution_count": 41, "outputs": [] }, { "cell_type": "markdown", "source": [ "We can export displacements $\\bf u$ and von Mises stress $\\sigma_\\text{vM}$ to a XDMF file for visualization in ParaView. We rename the value of function $u$, such that it will have a meaningful name in ParaView." ], "metadata": { "id": "3y2F-iCnWEQM" } }, { "cell_type": "code", "source": [ "xdmf = io.XDMFFile(domain.comm, \"clamped_deformation.xdmf\", \"w\")\n", "xdmf.write_mesh(domain)\n", "u.name = \"displacements\"\n", "xdmf.write_function(u)\n", "stresses.name = \"von Mises\"\n", "xdmf.write_function(stresses)\n", "xdmf.close()" ], "metadata": { "id": "964uAly7WKXl" }, "execution_count": 42, "outputs": [] }, { "cell_type": "markdown", "source": [ "# Cahn-Hilliard equation\n", "\n", "This example illustrates how to:\n", "\n", "- Solve time evolution of non-linear PDEs;\n", "- Implement initial conditions with small random perturbation.\n", "\n", "Note that this example is based on the FEniCS demo: click here." ], "metadata": { "id": "U75B_4asPfQb" } }, { "cell_type": "markdown", "source": [ "## Equation and problem definition" ], "metadata": { "id": "YoW4SpwEP7o8" } }, { "cell_type": "markdown", "source": [ "The Cahn-Hilliard equation describes the process of phase separation, by which the two components of a binary fluid spontaneously separate and form domains enriched in one of the two components. The driving force for the phase separation is the tendency of the system to lower the total free energy\n", "$$G[c] = \\int_\\Omega d{\\bf x}\\, \\left[f(c) + \\frac{1}{2}\\lambda (\\nabla c)^2\\right],$$\n", "where $c$ is an order parameter and the two phases correspond to $c=0$ and $c=1$. The first term in the above equation describes the bulk free energy and the second term the interfacial energy between the two phases. The bulk free energy density is commonly described with the double well potential and in this example we use the free energy density $f(c)=100 c^2 (1-c)^2$." ], "metadata": { "id": "2QBiA3yPP_a8" } }, { "cell_type": "markdown", "source": [ "To describe the kinetics of the phase separation process it is convenient to first introduce the chemical potential $\\mu$, which can be obtained as the functional derivative of the free energy. More precisely, we calculate the variation of the free energy $G[c+\\delta c]=G[c]+\\delta G$, where the variation is\n", "$$\\delta G= \\int_\\Omega d{\\bf x} \\ \\left[f'(c) \\delta c + \\lambda \\nabla c \\cdot \\nabla \\delta c\\right]=\\int_\\Omega d{\\bf x}\\ \\left[f'(c) - \\lambda (\\nabla^2 c) \\right] \\delta c \\equiv \\int_\\Omega d{\\bf x}\\ \\mu \\delta c,$$\n", "where we used integration by parts and defined the chemical potential\n", "$$\\mu = f'(c) - \\lambda \\nabla^2 c.$$\n", "The gradients of the chemical potential provide the driving force for the redistribution of material, and this kinetics is described with\n", "$$\\frac{\\partial c}{\\partial t} = \\nabla \\cdot (M \\nabla \\mu),$$\n", "where $M$ is the mobility." ], "metadata": { "id": "fLK-igaIQC_n" } }, { "cell_type": "markdown", "source": [ "### Discretizaton of time \n", "\n", "In order to solve the two coupled PDEs for the concentration $c({\\bf x},t)$ and chemical potential $\\mu({\\bf x},t)$, we first discuss the time discretization. Fields are evaluated at discrete timesteps $t_n = n \\Delta t$, where $n=0,1,2,\\ldots$. We use the notation $c_{n}({\\bf x})\\equiv c({\\bf x},t_n)$ and $\\mu_{n}({\\bf x})\\equiv \\mu({\\bf x},t_n)$. The two coupled PDEs can then be written as \n", " \\begin{aligned}\n", " \\frac{c_{n+1}-c_{n}}{\\Delta t} &= \\nabla \\cdot (M \\nabla \\mu_{n+\\theta}),\\\\\n", " \\mu_{n+1} &= f'(c_{n+1}) - \\lambda \\nabla^2 c_{n+1},\\\\\n", " \\end{aligned} \n", "where $\\mu_{n+\\theta} = (1-\\theta) \\mu_{n} + \\theta \\mu_{n+1}$. Different choices for the parameter $\\theta$ correspond to the forward Euler method ($\\theta=0$), the backward Euler method ($\\theta=1$), and the Crank–Nicolson method ($\\theta=1/2$). Check the Wikipedia article for more information about the differences between these three methods. In this example we use the Crank–Nicolson method ($\\theta=1/2$). The general procedure is to start with the initial concentrations $c_0({\\bf x})$, from which we can calculate the chemical potentials $\\mu_0({\\bf x})$ at time 0. Then we iteratively calculate the fields ($c_{n+1}$, $\\mu_{n+1}$) at time $t_{n+1}$ from the values of fields ($c_{n+1}$, $\\mu_{n+1}$) at time $t_n$." ], "metadata": { "id": "t9gi5FR1QHao" } }, { "cell_type": "markdown", "source": [ "### Weak formulation of the problem\n", "\n", "The final step is to write the weak formulation of the coupled PDEs\n", " \\begin{aligned}\\int_\\Omega d{\\bf x} \\\n", " \\left[\\frac{c_{n+1}-c_{n}}{\\Delta t} - \\nabla \\cdot (M \\nabla \\mu_{n+\\theta})\\right] q & = 0,\\\\\n", " \\int_\\Omega d{\\bf x} \\ \\left[\\mu_{n+1} - f'(c_{n+1}) + \\lambda \\nabla^2 c_{n+1}\\right] v & = 0,\\\\\n", " \\end{aligned}\n", "where we introduced two *test functions* $q$ and $v$. After the integration by parts the two coupled PDEs can be rewritten as\n", " \\begin{aligned}\\int_\\Omega d{\\bf x} \\\n", " \\left[\\frac{c_{n+1}-c_{n}}{\\Delta t} q + M \\nabla \\mu_{n+\\theta} \\cdot \\nabla q\\right] & = 0,\\\\\n", " \\int_\\Omega d{\\bf x} \\ \\left[\\mu_{n+1} v - f'(c_{n+1})v - \\lambda \\nabla c_{n+1} \\cdot \\nabla v\\right] & = 0.\\\\\n", " \\end{aligned}\n", "In these example, we solve the Cahn-Hilliard equation on a unit square domain with periodic boundary conditions. The intial concentration values are chosen randomly on the interval $(0.62,0.64)$. Other values are chosen as in the FEniCS demo, i.e. $\\lambda = 10^{-2}$ and $\\Delta t = 5 \\times 10^{-6}$." ], "metadata": { "id": "iyavN4JNQMjL" } }, { "cell_type": "markdown", "source": [ "## Implementation" ], "metadata": { "id": "UHSN5lF5Ql5d" } }, { "cell_type": "markdown", "source": [ "As usual, in order to use solve this problem we need to import all necessary modules." ], "metadata": { "id": "X-36PjXLQryh" } }, { "cell_type": "code", "source": [ "from dolfinx import *\n", "import gmsh\n", "from dolfinx.io import gmshio\n", "from mpi4py import MPI\n", "from petsc4py.PETSc import ScalarType\n", "from ufl import *\n", "import pyvista\n", "pyvista.start_xvfb()" ], "metadata": { "id": "ueugGB4ROl-f" }, "execution_count": 43, "outputs": [] }, { "cell_type": "markdown", "source": [ "Next, we create a mesh for a unit square domain and define the function space, where we use quadrilateral elements. Here we use mixed elements, where the first ellement corresponds to the concentration field $c$ and the second element to the chemical potential field $\\mu$. " ], "metadata": { "id": "CAMT2EqTRGTn" } }, { "cell_type": "code", "source": [ "# Create mesh and define function space with periodic boundary conditions\n", "domain = mesh.create_unit_square(MPI.COMM_WORLD, 100, 100, mesh.CellType.quadrilateral)\n", "P = FiniteElement('Lagrange', domain.ufl_cell(), 1)\n", "MFS = fem.FunctionSpace(domain, MixedElement([P,P]))" ], "metadata": { "id": "4AMuGfj5Q8P6" }, "execution_count": 44, "outputs": [] }, { "cell_type": "markdown", "source": [ "We define functions ${\\bf u}_{new}$ and ${\\bf u}_{old}$, where we store fields $(c_{n+1},\\mu_{n+1})$ and $(c_{n},\\mu_{n})$, respectively. We also split the function into the concentration and chemical potential fields. In a similar way we introduce the test function, which is split into two test functions $q$ and $v$." ], "metadata": { "id": "5B3z5yAZRUnG" } }, { "cell_type": "code", "source": [ "# Define functions\n", "u_new = fem.Function(MFS) # solution for the next step\n", "u_old = fem.Function(MFS) # solution from previous step\n", "# Split mixed functions\n", "c_new, mu_new = split(u_new)\n", "c_old, mu_old = split(u_old)\n", "\n", "# Define test functions\n", "tf = TestFunction(MFS)\n", "q, v = split(tf)" ], "metadata": { "id": "6IpmcD_ORSVe" }, "execution_count": 45, "outputs": [] }, { "cell_type": "markdown", "source": [ "To prescribe intitial conditions with the concentration values that are chosen randomly from the interval $(0.62,0.64)$ we implement the anonymous lambda function and interpolate it on the appropriate subspace. In the constructor `(__init__)`, the random number generator is seeded." ], "metadata": { "id": "SN7z2uXBRgjt" } }, { "cell_type": "code", "source": [ "# Interpolate initial condition\n", "u_new.x.array[:] = 0.0\n", "u_new.sub(0).interpolate(lambda x: 0.63 + 0.02 * (0.5 - np.random.rand(x.shape[1])))\n", "u_new.x.scatter_forward()" ], "metadata": { "id": "V-M7-V5sRY8X" }, "execution_count": 46, "outputs": [] }, { "cell_type": "markdown", "source": [ "To calculate the contribution $f'(c)$ for the chemical potential we use automated differentiation. The first line declares that $c$ is a variable that some function can be differentiated with respect to. The next line is the function $f=100 c^2 (1-c)^2$ defined in the problem statement, and the third line performs the differentiation of $f$ with respect to the variable $c$." ], "metadata": { "id": "HLrAL72aRxii" } }, { "cell_type": "code", "source": [ "# Compute the chemical potential df/dc\n", "c_new = variable(c_new)\n", "f = 100*c_new**2*(1-c_new)**2\n", "dfdc = diff(f, c_new)" ], "metadata": { "id": "3N7ROOXHRvCV" }, "execution_count": 47, "outputs": [] }, { "cell_type": "markdown", "source": [ "Next we implement the weak form of coupled PDEs\n", " \\begin{aligned}\\int_\\Omega d{\\bf x} \\\n", " \\left[\\frac{c_{n+1}-c_{n}}{\\Delta t} q + M \\nabla \\mu_{n+\\theta} \\cdot \\nabla q\\right] & = 0,\\\\\n", " \\int_\\Omega d{\\bf x} \\ \\left[\\mu_{n+1} v - f'(c_{n+1})v - \\lambda \\nabla c_{n+1} \\cdot \\nabla v\\right] & = 0.\\\\\n", " \\end{aligned}" ], "metadata": { "id": "Cm-UUmCfR3Gv" } }, { "cell_type": "code", "source": [ "lmbda = 1.0e-02 # surface parameter\n", "dt = 5.0e-06 # time step\n", "theta = 0.5 # time stepping family, e.g. theta=1 -> backward Euler, theta=0.5 -> Crank-Nicolson\n", "\n", "# mu_(n+theta)\n", "mu_mid = (1.0-theta)*mu_old + theta*mu_new\n", "\n", "# Weak statement of the equations\n", "Res_0 = (c_new - c_old)/dt*q*dx + dot(grad(mu_mid), grad(q))*dx\n", "Res_1 = mu_new*v*dx - dfdc*v*dx - lmbda*dot(grad(c_new), grad(v))*dx\n", "Res = Res_0 + Res_1\n", "\n", "problem = fem.petsc.NonlinearProblem(Res, u_new)\n", "solver = nls.petsc.NewtonSolver(MPI.COMM_WORLD, problem)" ], "metadata": { "id": "1bslDfI2R0pQ" }, "execution_count": 48, "outputs": [] }, { "cell_type": "markdown", "source": [ "Prepare files, where we will store concentration and chemical potential fields for the visualization in ParaView.\n" ], "metadata": { "id": "oPwArenqSAIx" } }, { "cell_type": "code", "source": [ "file = io.XDMFFile(MPI.COMM_WORLD, \"ch_output.xdmf\", \"w\")\n", "file.write_mesh(domain)\n", "u_new.sub(0).name = \"concentrations\"\n", "u_new.sub(1).name = \"chemical potential\"" ], "metadata": { "id": "NhpIefKJR6I5" }, "execution_count": 49, "outputs": [] }, { "cell_type": "markdown", "source": [ "Iteratively solve the coupled PDEs for 50 time steps. At each step we first copy the values of fields from the ${\\bf u}_{new}$ function to the ${\\bf u}_{old}$ function. Then we solve the coupled PDEs and store the new values of fields in the function ${\\bf u}_{new}$. Finally, we save the values of fields for visualization in ParaView " ], "metadata": { "id": "agkr3dNdSNzs" } }, { "cell_type": "code", "source": [ "# Step in time\n", "t = 0.0\n", "T = 50*dt\n", "file.write_function(u_new.sub(0), t)\n", "file.write_function(u_new.sub(1), t)\n", "while (t < T):\n", " t += dt\n", " print(t)\n", " u_old.x.array[:] = u_new.x.array\n", " solver.solve(u_new)\n", " file.write_function(u_new.sub(0), t)\n", " file.write_function(u_new.sub(1), t)\n", "file.close()" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "ZcMWO7HYSKjK", "outputId": "76434217-76d0-4409-8fb7-6bbe20b31aa2" }, "execution_count": 50, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "5e-06\n", "1e-05\n", "1.5000000000000002e-05\n", "2e-05\n", "2.5e-05\n", "3e-05\n", "3.5000000000000004e-05\n", "4e-05\n", "4.5e-05\n", "5e-05\n", "5.5e-05\n", "6e-05\n", "6.500000000000001e-05\n", "7.000000000000001e-05\n", "7.500000000000001e-05\n", "8e-05\n", "8.5e-05\n", "9e-05\n", "9.5e-05\n", "0.0001\n", "0.000105\n", "0.00011\n", "0.000115\n", "0.00012\n", "0.000125\n", "0.00013000000000000002\n", "0.00013500000000000003\n", "0.00014000000000000004\n", "0.00014500000000000006\n", "0.00015000000000000007\n", "0.00015500000000000008\n", "0.0001600000000000001\n", "0.0001650000000000001\n", "0.00017000000000000012\n", "0.00017500000000000013\n", "0.00018000000000000015\n", "0.00018500000000000016\n", "0.00019000000000000017\n", "0.00019500000000000019\n", "0.0002000000000000002\n", "0.0002050000000000002\n", "0.00021000000000000023\n", "0.00021500000000000024\n", "0.00022000000000000025\n", "0.00022500000000000026\n", "0.00023000000000000028\n", "0.0002350000000000003\n", "0.0002400000000000003\n", "0.0002450000000000003\n", "0.00025000000000000033\n" ] } ] }, { "cell_type": "code", "source": [], "metadata": { "id": "Fl2A2-RnSQdg" }, "execution_count": null, "outputs": [] } ] }