diff --git a/book/_toc.yml b/book/_toc.yml index 17f7119..4865117 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -30,4 +30,5 @@ parts: - file: content/applications/task08 - file: content/applications/task09 - file: content/applications/task06 - - file: content/applications/task10 \ No newline at end of file + - file: content/applications/task10 + - file: content/advection \ No newline at end of file diff --git a/book/content/advection.ipynb b/book/content/advection.ipynb new file mode 100644 index 0000000..dcd6a2e --- /dev/null +++ b/book/content/advection.ipynb @@ -0,0 +1,389 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b782b819", + "metadata": {}, + "source": [ + "# Advection-diffusion problem (multi-material)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "e4509407", + "metadata": {}, + "outputs": [], + "source": [ + "from mpi4py import MPI\n", + "\n", + "import dolfinx\n", + "import numpy as np\n", + "import basix\n", + "import festim as F\n", + "\n", + "n =50\n", + "\n", + "def bottom_boundary(x):\n", + " return np.isclose(x[1], 0.0)\n", + "\n", + "def top_boundary(x):\n", + " return np.isclose(x[1], 1.0)\n", + "\n", + "def bottom_left_boundary(x):\n", + " return np.logical_and(np.isclose(x[0], 0.0), x[1] <= 0.5 + 1e-14)\n", + "\n", + "def half(x):\n", + " return x[1] <= 0.5 + 1e-14\n", + "\n", + "mesh = dolfinx.mesh.create_unit_square(\n", + " MPI.COMM_WORLD, n, n, dolfinx.mesh.CellType.triangle\n", + ")\n", + "\n", + "# Split domain in half and set an interface tag of 5\n", + "gdim = mesh.geometry.dim\n", + "tdim = mesh.topology.dim\n", + "fdim = tdim - 1\n", + "top_facets = dolfinx.mesh.locate_entities_boundary(mesh, fdim, top_boundary)\n", + "bottom_facets = dolfinx.mesh.locate_entities_boundary(mesh, fdim, bottom_boundary)\n", + "bot_left_facets = dolfinx.mesh.locate_entities_boundary(\n", + " mesh, fdim, bottom_left_boundary\n", + ")\n", + "num_facets_local = (\n", + " mesh.topology.index_map(fdim).size_local\n", + " + mesh.topology.index_map(fdim).num_ghosts\n", + ")\n", + "facets = np.arange(num_facets_local, dtype=np.int32)\n", + "values = np.full_like(facets, 0, dtype=np.int32)\n", + "values[top_facets] = 1\n", + "values[bottom_facets] = 2\n", + "values[bot_left_facets] = 3\n", + "\n", + "bottom_cells = dolfinx.mesh.locate_entities(mesh, tdim, half)\n", + "num_cells_local = (\n", + " mesh.topology.index_map(tdim).size_local\n", + " + mesh.topology.index_map(tdim).num_ghosts\n", + ")\n", + "cells = np.full(num_cells_local, 5, dtype=np.int32)\n", + "cells[bottom_cells] = 4\n", + "ct = dolfinx.mesh.meshtags(\n", + " mesh, tdim, np.arange(num_cells_local, dtype=np.int32), cells\n", + ")\n", + "all_b_facets = dolfinx.mesh.compute_incident_entities(\n", + " mesh.topology, ct.find(4), tdim, fdim\n", + ")\n", + "all_t_facets = dolfinx.mesh.compute_incident_entities(\n", + " mesh.topology, ct.find(5), tdim, fdim\n", + ")\n", + "interface = np.intersect1d(all_b_facets, all_t_facets)\n", + "values[interface] = 6\n", + "\n", + "mt = dolfinx.mesh.meshtags(mesh, mesh.topology.dim - 1, facets, values)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a91742d1", + "metadata": {}, + "outputs": [], + "source": [ + "def create_velocity_field():\n", + " def velocity_func(x):\n", + " values = np.zeros((2, x.shape[1])) # Initialize with zeros\n", + " scalar_value = -1000 * x[1] * (x[1] - 0.5) # Compute the scalar function\n", + " values[0] = scalar_value # Assign to first component\n", + " values[1] = 0 # Second component remains zero\n", + " return values\n", + "\n", + " submesh, submesh_to_mesh, v_map = dolfinx.mesh.create_submesh(\n", + " mesh, ct.dim, ct.find(4)\n", + " )[0:3]\n", + " v_cg = basix.ufl.element(\n", + " \"Lagrange\", submesh.topology.cell_name(), 2, shape=(submesh.geometry.dim,)\n", + " )\n", + " V_velocity = dolfinx.fem.functionspace(submesh, v_cg)\n", + " u = dolfinx.fem.Function(V_velocity)\n", + " u.interpolate(velocity_func)\n", + " return u\n", + "\n", + "\n", + "u = create_velocity_field()\n", + "\n", + "writer = dolfinx.io.VTXWriter(MPI.COMM_WORLD, \"velocity.bp\", u, engine=\"BP5\")\n", + "writer.write(t=0)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "c2a88a52", + "metadata": {}, + "outputs": [], + "source": [ + "from dolfinx import plot\n", + "import pyvista\n", + "\n", + "pyvista.start_xvfb()\n", + "pyvista.set_jupyter_backend(\"html\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "42c527ce", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ec6a05530c26467c8338481a55dcb5f5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "EmbeddableWidget(value='