Skip to content

Constant boundary conditions and ufl.Expression interpolation #56

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

Merged
merged 3 commits into from
Dec 26, 2021
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
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Changelog

## Dev
- 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).
- Various API changes relating to the import structure of DOLFINx

## 0.3.0 (09.09.2021)
Expand Down
49 changes: 25 additions & 24 deletions chapter1/fundamentals_code.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
"\n",
"In this section, you will learn:\n",
"- How to use the built-in meshes in DOLFINx\n",
"- How to create a Dirichlet boundary conditions on the whole domain boundary\n",
"- How to create a spatially varying Dirichlet boundary conditions on the whole domain boundary\n",
"- How to define a weak formulation of your PDE\n",
"- How to solve the resulting system of linear equations\n",
"- How to visualize the solution using a variety of tools\n",
"- How to compute the $L^2(\\Omega)$ error and the error at mesh vertices\n",
"\n",
"## Interactive tutorials\n",
"```{admonition} Run the tutorial as Jupyter notebook in browser\n",
"As this book has been published as a Jupyter Book, each code can be run in your browser as a Jupyter notebook. To start such a notebook click the rocket symbol in the top right corner of the relevant tutorial.\n",
Expand Down Expand Up @@ -63,7 +64,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -94,7 +95,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -125,7 +126,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -146,7 +147,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -175,7 +176,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -193,12 +194,12 @@
"In mathematics, we distinguish between trial and test spaces $V$ and $\\hat{V}$. The only difference in the present problem is the boundary conditions.\n",
"In FEniCSx, we do not specify boundary conditions as part of the function space, so it is sufficient to use a common space for the trial and test function.\n",
"\n",
"We use the [Unified Form Language](https://github.com/FEniCS/ufl/) (UFL) to specify the varitional formulations."
"We use the [Unified Form Language](https://github.com/FEniCS/ufl/) (UFL) to specify the varitional formulations. See {cite}`ufl2014` for more details."
]
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -217,7 +218,7 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -240,7 +241,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -256,7 +257,7 @@
"$\\int_{\\Omega} \\nabla u \\cdot \\nabla v ~\\mathrm{d} x$ and $\\int_{\\Omega}fv~\\mathrm{d} x$. \n",
"The integration over the domain $\\Omega$ is defined by using `ufl.dx`, an integration measure over all cells of the mesh.\n",
"\n",
"This is the key strength of FEniCSx: the formulas in the variational formulation translate directly to very similar Python code, a feature that makes it easy to specify and solve complicated PDE problems. The language used to express weak forms is the Unified Form Language [UFL](https://doi.org/10.1145/2566630).\n",
"This is the key strength of FEniCSx: the formulas in the variational formulation translate directly to very similar Python code, a feature that makes it easy to specify and solve complicated PDE problems.\n",
"\n",
"## Expressing inner products\n",
"The inner product $\\int_\\Omega \\nabla u \\cdot \\nabla v ~\\mathrm{d} x$ can be expressed in various ways in UFL. We have used the notation `ufl.dot(ufl.grad(u), ufl.grad(v))*ufl.dx`. The dot product in UFL computes the sum (contraction) over the last index of the first factor and first index of the second factor. In this case, both factors are tensors of rank one (vectors) and so the sum is just over the single index of both $\\nabla u$ and $\\nabla v$. To compute an inner product of matrices (with two indices), one must instead of `ufl.dot` use the function `ufl.inner`. For vectors, `ufl.dot` and `ufl.inner` are equivalent.\n",
Expand All @@ -276,7 +277,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -289,14 +290,14 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Using `problem.solve()` we solve the linear system of equations and return a `dolfinx.Function` containing the solution.\n",
"Using `problem.solve()` we solve the linear system of equations and return a `dolfinx.fem.Function` containing the solution.\n",
"## Computing the error\n",
"Finally, we want to compute the error to check the accuracy of the solution. We do this by comparing the finite element solution `u` with the exact solution. We do this by interpolating the exact solution into the the $P_2$-function space."
]
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -315,7 +316,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -339,7 +340,7 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 13,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -373,7 +374,7 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -383,7 +384,7 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -400,7 +401,7 @@
},
{
"cell_type": "code",
"execution_count": 24,
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -421,13 +422,13 @@
},
{
"cell_type": "code",
"execution_count": 26,
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "cee1088755b04b99bdedbc3bf73335a3",
"model_id": "52f926f800b84003bd2eda5e14ba1871",
"version_major": 2,
"version_minor": 0
},
Expand Down Expand Up @@ -460,13 +461,13 @@
},
{
"cell_type": "code",
"execution_count": 27,
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "9d3ee0699fb744d8b619d2cf7f4af5d2",
"model_id": "6b86e726693d42f3b675cea1633f9136",
"version_major": 2,
"version_minor": 0
},
Expand Down Expand Up @@ -496,7 +497,7 @@
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
Expand Down
Loading