Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update all tutorials with new API and new plotting #57

Merged
merged 3 commits into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/build-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
container: dokken92/dolfinx_custom:26122021
container: dokken92/dolfinx_custom:07012022

env:
HDF5_MPI: "ON"
Expand All @@ -35,12 +35,11 @@ jobs:
- uses: actions/checkout@v2

- name: Install dependencies
run: pip3 install notebook nbconvert "jupyter-book<6" --upgrade
run: pip3 install notebook nbconvert jupyter-book --upgrade
- name: Test notebooks in parallel
run: |
cd chapter1
jupyter-nbconvert --to python fundamentals_code.ipynb
python3 -c "from pyvista import start_xvfb; start_xvfb(0.1)"
mpirun -n 2 python3 fundamentals_code.py
jupyter-nbconvert --to python membrane_code.ipynb
mpirun -n 2 python3 membrane_code.py
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ jobs:
run: echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
- name: Push to the DockerHub registry
run: |
docker push dokken92/dolfinx_custom:26122021
docker push dokken92/dolfinx_custom:07012022
10 changes: 5 additions & 5 deletions .github/workflows/main-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,22 @@ jobs:

- name: Install dependencies
run: |
wget -qO - https://deb.nodesource.com/setup_17.x | bash
CC=mpicc HDF_MPI="ON" HDF5_DIR="/usr/lib/x86_64-linux-gnu/hdf5/mpich/" pip3 install --no-cache-dir --no-binary=h5py h5py meshio
apt-get -qq update
apt-get install -y libgl1-mesa-dev xvfb nodejs
apt-get clean
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
CC=mpicc HDF_MPI="ON" HDF5_DIR="/usr/lib/x86_64-linux-gnu/hdf5/mpich/" pip3 install --no-cache-dir --no-binary=h5py h5py meshio
pip3 install --no-cache-dir tqdm pandas seaborn
pip3 install notebook nbconvert jupyter-book myst_parser pyvista jupyterlab
pip3 install --no-cache-dir matplotlib itkwidgets ipywidgets setuptools --upgrade
jupyter labextension install jupyter-matplotlib jupyterlab-datawidgets && \
pip3 install ipygany pythreejs
pip3 install --no-cache-dir matplotlib setuptools --upgrade
jupyter nbextension enable --py --sys-prefix ipygany
rm -rf /usr/local/share/.cache/*
- name: Test notebooks in parallel
run: |
cd chapter1
jupyter-nbconvert --to python fundamentals_code.ipynb
python3 -c "from pyvista import start_xvfb; start_xvfb(0.1)"
jupyter-nbconvert --to python fundamentals_code.ipynb
mpirun -n 2 python3 fundamentals_code.py
jupyter-nbconvert --to python nitsche.ipynb
mpirun -n 2 python3 nitsche.py
Expand Down
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Changelog

## Dev
- API updates wrt. DOLFINx. `Form`->`form`, `DirichletBC`->`dirichletbc`.
- Switch plotting backend to `ipygany` and `pythreejs`
- Updates on error computations in [Error control: Computing convergence rates](chapter4/convergence).
- Added tutorial on interpolation of `ufl.Expression` in [Deflection of a membrane](chapter1/membrane_code).
- Added tutorial on how to apply constant-valued Dirichet conditions in [Deflection of a membrane](chapter1/membrane_code).
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM dokken92/dolfinx_custom:26122021
FROM dokken92/dolfinx_custom:07012022

# create user with a home directory
ARG NB_USER
Expand Down
84 changes: 45 additions & 39 deletions chapter1/fundamentals_code.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -95,7 +95,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -126,7 +126,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -147,7 +147,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -176,13 +176,13 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"from dolfinx.fem import locate_dofs_topological, DirichletBC\n",
"from dolfinx.fem import locate_dofs_topological, dirichletbc\n",
"boundary_dofs = locate_dofs_topological(V, fdim, boundary_facets)\n",
"bc = DirichletBC(uD, boundary_dofs)"
"bc = dirichletbc(uD, boundary_dofs)"
]
},
{
Expand All @@ -199,7 +199,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -218,7 +218,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -241,7 +241,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -277,7 +277,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -297,7 +297,7 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -316,12 +316,12 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"from dolfinx.fem import assemble_scalar\n",
"L2_error = ufl.inner(uh - uex, uh - uex) * ufl.dx\n",
"from dolfinx.fem import assemble_scalar, form\n",
"L2_error = form(ufl.inner(uh - uex, uh - uex) * ufl.dx)\n",
"error_local = assemble_scalar(L2_error)\n",
"error_L2 = numpy.sqrt(mesh.comm.allreduce(error_local, op=MPI.SUM))"
]
Expand All @@ -340,7 +340,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 12,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -374,37 +374,46 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"from dolfinx.plot import create_vtk_topology\n",
"topology, cell_types = create_vtk_topology(mesh, mesh.topology.dim)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There are several backends that can be used with pyvista, and they have different benefits and drawbacks. See the [pyvista documentation](https://docs.pyvista.org/user-guide/jupyter/index.html) for more information and installation details. In this example and the rest of the tutorial we will use [ipygany](https://github.com/QuantStack/ipygany) and [pythreejs](https://github.com/jupyter-widgets/pythreejs)."
]
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"import pyvista\n",
"grid = pyvista.UnstructuredGrid(topology, cell_types, mesh.geometry.x)"
"pyvista.set_jupyter_backend(\"pythreejs\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We start by creating a pyvista grid the `vtk_topology` and the `mesh.geometry`.\n",
"Next, we attach data from our solution `uh` by computing the values of the function at each vertex."
]
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"grid = pyvista.UnstructuredGrid(topology, cell_types, mesh.geometry.x)\n",
"grid.point_data[\"u\"] = uh.compute_point_values().real\n",
"grid.set_active_scalars(\"u\")"
]
Expand All @@ -414,65 +423,62 @@
"metadata": {},
"source": [
"We can now use the `pyvista.Plotter` to visualize the solution. We visualize it by showing it in 2D and warped in 3D.\n",
"In the jupyter notebook environment, we use the default setting of `pyvista.OFF_SCREEN=False`, which will render plots directly in the notebook. . PYVITo render in the online notebooks or in docker containers without X-forwarding, we need to start a virtual framebuffer.\n",
"```{admonition} Rendering with pyvista using Docker-containers\n",
"To make the plots render, we have to call `pyvista.start_xvfb` to start a virtual framebuffer if using docker-containers or jupyter notebooks on Linux.\n",
"```"
"In the jupyter notebook environment, we use the default setting of `pyvista.OFF_SCREEN=False`, which will render plots directly in the notebook."
]
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "52f926f800b84003bd2eda5e14ba1871",
"model_id": "026dd4bdc8354af88ecd23be302ee96c",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"ViewInteractiveWidget(height=768, layout=Layout(height='auto', width='100%'), width=1024)"
"Renderer(camera=PerspectiveCamera(aspect=1.3333333333333333, children=(DirectionalLight(color='#fefefe', inten…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"pyvista.start_xvfb(wait=0.05)\n",
"plotter = pyvista.Plotter()\n",
"plotter.add_mesh(grid, show_edges=True, show_scalar_bar=True)\n",
"plotter.add_mesh(grid, show_edges=True)\n",
"plotter.view_xy()\n",
"if not pyvista.OFF_SCREEN:\n",
" plotter.show()\n",
"else:\n",
" pyvista.start_xvfb()\n",
" figure = plotter.screenshot(\"fundamentals.png\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Alternative plotting\n",
"To create a more interactive plot using pyvista in a Jupyter notebook we us `pyvista.ITKPlotter` which uses `itkwidgets`. To modify the visualization, click on the three bars in the top left corner."
"## ipygany\n",
"We change plotting from `pythreejs` to `ipygany` by initializing another `Plotter` with `jupyter_backend=\"ipygany\"`. We also warp the mesh by scalar to make use of the 3D plotting."
]
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "6b86e726693d42f3b675cea1633f9136",
"model_id": "2b14ac59f2cf4d129b2843ce038c4b90",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Viewer(geometries=[{'vtkClass': 'vtkPolyData', 'points': {'vtkClass': 'vtkPoints', 'name': '_points', 'numberO…"
"AppLayout(children=(VBox(children=(HTML(value='<h3>u</h3>'), Dropdown(description='Colormap:', options={'BrBG'…"
]
},
"metadata": {},
Expand All @@ -481,10 +487,10 @@
],
"source": [
"if not pyvista.OFF_SCREEN:\n",
" plotter_itk = pyvista.PlotterITK()\n",
" warped = grid.warp_by_scalar(\"u\", factor=0.5)\n",
" plotter_itk.add_mesh(warped)\n",
" plotter_itk.show(True)"
" warped = grid.warp_by_scalar()\n",
" plotter2 = pyvista.Plotter()\n",
" plotter2.add_mesh(warped, show_edges=True, show_scalar_bar=True)\n",
" plotter2.show(jupyter_backend=\"ipygany\")"
]
},
{
Expand All @@ -497,7 +503,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
Expand Down
Loading