My feedback thread for website patches

Hi. As I am going through the tutorial, I thought to send patches to improve the website. I don’t have an account with Microsoft (GitHub). I don’t need acknowledgement.

This is on c9214c68438ab27d2fa8936307027c5209272162 GitHub - jorgensd/dolfinx-tutorial: A reimplementation of the Springer book: https://github.com/hplgit/fenics-tutorial/, covering new topics as well as transitioning from dolfin to dolfinx

From 707a8306457fedb295b0c2aae53d88ae905a0843 Mon Sep 17 00:00:00 2001
From: edgar <edgar [- no @ ] fenicsproject.discourse.group>
Date: Mon, 2 Oct 2023 11:47:46 +0200
Subject: [RFC PATCH] fundamentals_code: supported elements

---
 chapter1/fundamentals_code.ipynb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/chapter1/fundamentals_code.ipynb b/chapter1/fundamentals_code.ipynb
index 28ee96f..944b1f3 100644
--- a/chapter1/fundamentals_code.ipynb
+++ b/chapter1/fundamentals_code.ipynb
@@ -122,10 +122,10 @@
    "metadata": {},
    "source": [
     "The second argument is the tuple containing the type of finite element, and the element degree. The type of element here is \"CG\", which implies the standard Lagrange family of elements. \n",
-    "DOLFINx supports a large variety on elements on simplices \n",
+    "DOLFINx supports a large variety of elements on simplices \n",
     "(triangles and tetrahedra) and non-simplices (quadrilaterals\n",
     "and hexahedra). For an overview, see:\n",
-    "*FIXME: Add link to all the elements we support*\n",
+    "https://github.com/FEniCS/basix/blob/main/README.md#supported-elements\n",
     "\n",
     "The element degree in the code is 1. This means that we are choosing the standard $P_1$ linear Lagrange element, which has degrees of freedom at the vertices. \n",
     "The computed solution will be continuous across elements and linearly varying in $x$ and $y$ inside each element. Higher degree polynomial approximations are obtained by increasing the degree argument. \n",

base-commit: c9214c68438ab27d2fa8936307027c5209272162
-- 
2.42.0

If this is not the right place, let me know.

From commit 0fe6c20



From 71a8ad85c2fb57e7e1306b5d875f5f250803a660 Mon Sep 17 00:00:00 2001
From: edgar 
Date: Fri, 20 Oct 2023 20:50:02 +0200
Subject: [RFC PATCH] Squashed commit of the following:

commit f63be0716cb3a95900aed09b001bac6686cddbd7
Author: @ <@>
Date:   Fri Oct 20 15:55:45 2023 +0200

    nonlinpoisson_code: have replace -> have to replace

commit 8e65c79ec23f4f26da3390acef15c3d8282f33fc
Author: @ <@>
Date:   Wed Oct 11 17:08:40 2023 +0200

    subdomains: u_bc is not used

commit 2a89a6c71533c04347194ff97bfae1b25168acdc
Author: @ <@>
Date:   Fri Oct 20 17:07:30 2023 +0200

    GMSH -> Gmsh (everywhere, incl. Changelog.md)

commit 4914082e5581a4e64aeeed9174ecfe37c294b375
Author: edgar 
Date:   Tue Oct 10 17:16:48 2023 +0200

    subdomains: whose both has -> both of which have

commit f3cc9f7050e8c10d6ff6dd1d7d7afa72c5995698
Author: edgar 
Date:   Tue Oct 10 12:42:55 2023 +0200

    subdomains: fucntion -> function

commit b73fac5e587f75451d4551136c906047aec3b56a
Author: edgar 
Date:   Mon Oct 9 19:38:26 2023 +0200

    heat_equation: an projection -> a projection

commit 7b88c50a21a8cd96b03c2dc3c5f08fe32b665b7e
Author: edgar 
Date:   Fri Oct 6 19:21:04 2023 +0200

    fundamentals_code: to defined -> to define

commit fc38fd5976fe53ac9b16b3f1c9d6a9e5f7afc559
Author: edgar 
Date:   Fri Oct 6 15:02:09 2023 +0200

    linearelasticity_code: amtrix -> matrix

commit e23f947f6e92979bbf69fe32b66410f55b6da393
Author: edgar 
Date:   Fri Oct 6 00:11:32 2023 +0200

    linearelasticity_code: FunctionSpace needs shape parameter

commit bcd00be673280db9e168a485e3455578d6eee0e9
Author: edgar 
Date:   Fri Oct 6 00:11:11 2023 +0200

    linearelasticity_code: which locate -> which locates

commit 9c14f0c7d913bab4c0cc692250431edb2ef3def3
Author: edgar 
Date:   Thu Oct 5 20:22:15 2023 +0200

    linearelasticity_code: VectorFunctionSpace -> FunctionSpace; ufl.VectorElement -> basix.ufl.element; rephrase

commit dea442c4c7805402ed5a855d9a975c0c5843cd17
Author: edgar 
Date:   Wed Oct 4 21:05:35 2023 +0200

    linearelasticity_code: `ufl`s -> `ufl`'s

commit 27c9fb720dfc372294d58050bd170a15bf0dabe4
Author: edgar 
Date:   Wed Oct 4 18:03:59 2023 +0200

    elasticity_scaling: in this case -> is the case here

commit 6a651cad23c7390bde9353887f0671641a16095e
Author: edgar 
Date:   Wed Oct 4 16:55:16 2023 +0200

    elasticity_scaling: (rephrase) avoid strange plots

commit d547315f809d8b7605d8d877675ffee0d493ec52
Author: edgar 
Date:   Wed Oct 4 11:02:33 2023 +0200

    _toc.yml: elasticity_scaling before linearelasticity_code

commit 54b879a0ed2646037f218b4dd6d0150946cb6ded
Author: edgar 
Date:   Tue Oct 3 22:45:04 2023 +0200

    linearelasticity_code: weigth -> weight

commit 1a37cfe9bb76ed03ea87b8f3d27635d878ebe900
Author: edgar 
Date:   Tue Oct 3 22:40:07 2023 +0200

    linearelasticity_code: x=0 -> $x=0$

commit a66ee90fc66d7274cda488756ff1d36d65fe46f1
Author: edgar 
Date:   Mon Oct 2 17:57:12 2023 +0200

    visualizing -> visualise

commit 1652536808f56ca1d2c90eb3f4d255194f03bcfe
Author: edgar 
Date:   Mon Oct 2 17:30:31 2023 +0200

    fundamentals_code: allready -> already

commit d868362bb42a81676b84c3d1470d9f092c86fdb1
Author: edgar 
Date:   Mon Oct 2 16:57:28 2023 +0200

    fundamentals_code: missing parenthesis

commit f23f2b70a6abdc580994a52765c0b111e844de4d
Author: edgar 
Date:   Mon Oct 2 16:44:04 2023 +0200

    fundamentals_code: the the -> the

commit 51332df0d1704efc8c78bb346ac87b7e6eb8193e
Author: edgar 
Date:   Mon Oct 2 15:18:58 2023 +0200

    fundamentals_code: as class -> a class

commit a7ee7d6d9accbaaeee0db3d55b41f5ba1b9b9ed7
Author: edgar 
Date:   Mon Oct 2 14:32:36 2023 +0200

    dolfinx.Constant -> fem.Constant

commit 7baac518826370b6b84682d3afad497ca09e4f6d
Author: edgar 
Date:   Mon Oct 2 13:39:08 2023 +0200

    first use of dof

commit 239ecb10b3086ff42f14454b79393e23b9648006
Author: edgar 
Date:   Mon Oct 2 13:38:25 2023 +0200

    fundamentals_code: supported elements
---
Range-diff:
1:  71a8ad8 = 1:  71a8ad8 Squashed commit of the following:

 Changelog.md                         | 22 +++++---------
 _toc.yml                             |  4 +--
 chapter1/fundamentals_code.ipynb     | 43 +++++++++++++++++++++-------
 chapter1/membrane_code.ipynb         | 12 ++++----
 chapter1/membrane_code.py            | 12 ++++----
 chapter2/elasticity_scaling.md       |  4 +--
 chapter2/heat_equation.md            |  2 +-
 chapter2/linearelasticity_code.ipynb | 19 ++++++------
 chapter2/nonlinpoisson_code.ipynb    |  2 +-
 chapter2/ns_code2.ipynb              |  8 +++---
 chapter2/ns_code2.py                 |  8 +++---
 chapter3/subdomains.ipynb            |  7 ++---
 chapter3/subdomains.py               |  4 +--
 13 files changed, 80 insertions(+), 67 deletions(-)

diff --git a/Changelog.md b/Changelog.md
index 18b5cf6..6436f20 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,15 +1,9 @@
 # Changelog
 
-## v0.7.0
-
-- Renamed `dolfinx.graph.create_adjacencylist` to `dolfinx.graph.adjacencylist`
-- Renamed `dolfinx.plot.create_vtk_mesh` to `dolfinx.plot.vtk_mesh`
-- `dolfinx.geometry.BoundingBoxTree` has been changed to `dolfinx.geometry.bb_tree`
-- `create_mesh` with Meshio has been modified. Note that you now need to pass dtype `np.int32` to the cell_data.
-- Update dolfinx petsc API. Now one needs to explicitly import `dolfinx.fem.petsc` and `dolfinx.fem.nls`, as PETSc is no longer a strict requirement. Replace `petsc4py.PETSc.ScalarType` with `dolfinx.default_scalar_type` in demos where we do not use `petsc4py` explicitly.
+## main
+- No changes
 
 ## v0.6.0
-
 - Remove `ipygany` and `pythreejs` as plotting backends. Using `panel`.
 - Add gif-output to [chapter2/diffusion_code] and [chapter2/hyperelasticity].
 - Replace `dolfinx.fem.Function.geometric_dimension` with `len(dolfinx.fem.Function)`
@@ -17,9 +11,9 @@
 - Improve mesh quality in [chapter3/em].
 - `jit_params` and `form_compiler_params` renamed to `*_options`.
 
-## v0.5.0
 
-- Using new GMSH interface in DOLFINx (`dolfinx.io.gmshio`) in all demos using GMSH
+## v0.5.0
+- Using new Gmsh interface in DOLFINx (`dolfinx.io.gmshio`) in all demos using Gmsh
 - Added a section on custom Newton-solvers, see [chapter4/newton-solver].
 - Various minor DOLFINx API updates. `dolfinx.mesh.compute_boundary_facets` -> `dolfinx.mesh.exterior_facet_indices` with slightly different functionality. Use `dolfinx.mesh.MeshTagsMetaClass.find` instead of `mt.indices[mt.values==value]`.
 - Various numpy updates, use `np.full_like`.
@@ -27,11 +21,9 @@
 - Add example of how to use `DOLFINx` in complex mode, see [chapter1/complex_mode].
 
 ## 0.4.1
-
 - No changes
 
 ## 0.4.0 (05.02.2021)
-
 - All `pyvista` plotting has been rewritten to use `ipygany` and `pythreejs` as well as using a cleaner interface.
 - `dolfinx.plot.create_vtk_topology` has been renamed to `dolfinx.plot.create_vtk_mesh` and can now be directly used as input to `pyvista.UnstructuredGrid`.
 - `dolfinx.fem.Function.compute_point_values` has been deprecated. Interpolation into a CG-1 is now the way of getting vertex values.
@@ -42,7 +34,6 @@
 - Various API changes relating to the import structure of DOLFINx
 
 ## 0.3.0 (09.09.2021)
-
 - Major improvements in [Form compiler parameters](chapter4/compiler_parameters), using pandas and seaborn for visualization of speed-ups gained using form compiler parameters.
 - API change: `dolfinx.cpp.la.scatter_forward(u.x)` -> `u.x.scatter_forward`
 - Various plotting updates due to new version of pyvista.
@@ -50,6 +41,7 @@
 - Internal updates due to bumping of jupyter-book versions
 - Various typos and capitalizations fixed by @mscroggs in [PR 35](https://github.com/jorgensd/dolfinx-tutorial/pull/35).
 
-## 0.1.0 (11.05.2021)
 
-- First tagged release of DOLFINx Tutorial, compatible with [DOLFINx 0.1.0](https://github.com/FEniCS/dolfinx/releases/tag/0.1.0).
+
+## 0.1.0 (11.05.2021)
+- First tagged release of DOLFINx Tutorial, compatible with [DOLFINx 0.1.0](https://github.com/FEniCS/dolfinx/releases/tag/0.1.0).
\ No newline at end of file
diff --git a/_toc.yml b/_toc.yml
index 3f46be0..71aed71 100644
--- a/_toc.yml
+++ b/_toc.yml
@@ -28,8 +28,8 @@ parts:
           - file: chapter2/nonlinpoisson_code
       - file: chapter2/linearelasticity
         sections:
-          - file: chapter2/linearelasticity_code
           - file: chapter2/elasticity_scaling
+          - file: chapter2/linearelasticity_code
       - file: chapter2/navierstokes
         sections:
           - file: chapter2/ns_code1
@@ -48,4 +48,4 @@ parts:
       - file: chapter4/solvers
       - file: chapter4/compiler_parameters
       - file: chapter4/convergence
-      - file: chapter4/newton-solver
\ No newline at end of file
+      - file: chapter4/newton-solver
diff --git a/chapter1/fundamentals_code.ipynb b/chapter1/fundamentals_code.ipynb
index 809af6a..7f94387 100644
--- a/chapter1/fundamentals_code.ipynb
+++ b/chapter1/fundamentals_code.ipynb
@@ -116,6 +116,28 @@
     "V = FunctionSpace(domain, (\"Lagrange\", 1))"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "a33a822e",
+   "metadata": {},
+   "source": [
+    "The second argument is the tuple containing the type of finite element, and the element degree. The type of element here is \"CG\", which implies the standard Lagrange family of elements. \n",
+    "DOLFINx supports a large variety of elements on simplices \n",
+    "(triangles and tetrahedra) and non-simplices (quadrilaterals\n",
+    "and hexahedra). For an overview, see:\n",
+    "https://github.com/FEniCS/basix/blob/main/README.md#supported-elements\n",
+    "\n",
+    "The element degree in the code is 1. This means that we are choosing the standard $P_1$ linear Lagrange element, which has degrees of freedom (dof) at the vertices. \n",
+    "The computed solution will be continuous across elements and linearly varying in $x$ and $y$ inside each element. Higher degree polynomial approximations are obtained by increasing the degree argument. \n",
+    "\n",
+    "## Defining the boundary conditions\n",
+    "\n",
+    "The next step is to specify the boundary condition $u=u_D$ on $\\partial\\Omega_D$, which is done by over several steps. \n",
+    "The first step is to define the function $u_D$. Into this function, we would like to interpolate the boundary condition $1 + x^2+2y^2$.\n",
+    "We do this by first defining a `dolfinx.fem.Function`, and then using a [lambda-function](https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions) in Python to define the \n",
+    "spatially varying function.\n"
+   ]
+  },
   {
    "cell_type": "code",
    "execution_count": 3,
@@ -226,7 +248,7 @@
    "metadata": {},
    "source": [
     "## Defining the source term\n",
-    "As the source term is constant over the domain, we use `dolfinx.Constant`"
+    "As the source term is constant over the domain, we use `fem.Constant`"
    ]
   },
   {
@@ -250,8 +272,8 @@
    "metadata": {},
    "source": [
     "```{admonition} Compilation speed-up\n",
-    "Instead of wrapping $-6$ in a `dolfinx.Constant`, we could simply define $f$ as `f=-6`.\n",
-    "However, if we would like to change this parameter later in the simulation, we would have to redefine our variational formulation. The `dolfinx.Constant` allows us to update the value in $f$ by using `f.value=5`. Additionally, by indicating that $f$ is a constant, we speed of compilation of the variational formulations required for the created linear system. \n",
+    "Instead of wrapping $-6$ in a `fem.Constant`, we could simply define $f$ as `f=-6`.\n",
+    "However, if we would like to change this parameter later in the simulation, we would have to redefine our variational formulation. The `fem.Constant` allows us to update the value in $f$ by using `f.value=5`. Additionally, by indicating that $f$ is a constant, we speed of compilation of the variational formulations required for the created linear system. \n",
     "```\n",
     "## Defining the variational problem\n",
     "As we now have defined all variables used to describe our variational problem, we can create the weak formulation"
@@ -296,9 +318,8 @@
     "\n",
     "## Forming and solving the linear system\n",
     "\n",
-    "Having defined the finite element variational problem and boundary condition, we can create our `dolfinx.fem.petsc.LinearProblem`, as class for solving \n",
-    "the variational problem: Find $u_h\\in V$ such that $a(u_h, v)==L(v) \\quad \\forall v \\in \\hat{V}$. We will use PETSc as our linear algebra backend, using a direct solver (LU-factorization).\n",
-    "See the [PETSc-documentation](https://petsc.org/main/docs/manual/ksp/?highlight=ksp#ksp-linear-system-solvers) of the method for more information.\n",
+    "Having defined the finite element variational problem and boundary condition, we can create our `dolfinx.fem.petsc.LinearProblem`, a class for solving \n",
+    "the variational problem: Find $u_h\\in V$ such that $a(u_h, v)==L(v) \\quad \\forall v \\in \\hat{V}$. We will use PETSc as our linear algebra backend, using a direct solver (LU-factorization). See the [PETSc-documentation](https://petsc.org/main/docs/manual/ksp/?highlight=ksp#ksp-linear-system-solvers) of the method for more information.\n",
     "PETSc is not a required dependency of DOLFINx, and therefore we explicitly import the DOLFINx wrapper for interfacing with PETSc."
    ]
   },
@@ -325,7 +346,7 @@
    "source": [
     "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."
+    "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 $P_2$-function space."
    ]
   },
   {
@@ -349,7 +370,7 @@
    "id": "1a2c3f62",
    "metadata": {},
    "source": [
-    "We compute the error in two different ways. First, we compute the $L^2$-norm of the error, defined by $E=\\sqrt{\\int_\\Omega (u_D-u_h)^2\\mathrm{d} x}$. We use UFL to express the $L^2$-error, and use `dolfinx.fem.assemble_scalar` to compute the scalar value. In DOLFINx, `assemble_scalar` only assembles over the cells on the local process. This means that if we use 2 processes to solve our problem, we need to gather the solution to one (or all the processes.\n",
+    "We compute the error in two different ways. First, we compute the $L^2$-norm of the error, defined by $E=\\sqrt{\\int_\\Omega (u_D-u_h)^2\\mathrm{d} x}$. We use UFL to express the $L^2$-error, and use `dolfinx.fem.assemble_scalar` to compute the scalar value. In DOLFINx, `assemble_scalar` only assembles over the cells on the local process. This means that if we use 2 processes to solve our problem, we need to gather the solution to one (or all the processes).\n",
     "We can do this with the `MPI.allreduce` function."
    ]
   },
@@ -379,7 +400,7 @@
     "$ u = \\sum_{j=1}^N U_j\\phi_j.$\n",
     "By writing `problem.solve()` we compute all the coefficients $U_1,\\dots, U_N$. These values are known as the _degrees of freedom_ (dofs). We can access the degrees of freedom by accessing the underlying vector in `uh`.\n",
     "However, as a second order function space has more dofs than a linear function space, we cannot compare these arrays directly.\n",
-    "As we allready have interpolated the exact solution into the first order space when creating the boundary condition, we can compare the maximum values at any degree of freedom of the approximation space."
+    "As we already have interpolated the exact solution into the first order space when creating the boundary condition, we can compare the maximum values at any degree of freedom of the approximation space."
    ]
   },
   {
@@ -415,7 +436,7 @@
    "metadata": {},
    "source": [
     "## Plotting the mesh using pyvista\n",
-    "We will visualizing the mesh using [pyvista](https://docs.pyvista.org/), an interface to the VTK toolkit.\n",
+    "We will visualise the mesh using [pyvista](https://docs.pyvista.org/), an interface to the VTK toolkit.\n",
     "We start by converting the mesh to a format that can be used with `pyvista`.\n",
     "To do this we use the function `dolfinx.plot.vtk_mesh`. The first step is to create an unstructured grid that can be used by `pyvista`.\n",
     "We need to start a virtual framebuffer for plotting through docker containers. You can print the current backend and change it with `pyvista.set_jupyter_backend(backend)`"
@@ -1231,7 +1252,7 @@
    "metadata": {},
    "source": [
     "## Plotting a function using pyvista\n",
-    "We want to plot the solution `uh`. As the function space used to defined the mesh is disconnected from the function space defining the mesh, we create a mesh based on the dof coordinates for the function space `V`. We use `dolfinx.plot.vtk_mesh` with the function space as input to create a mesh with mesh geometry based on the dof coordinates."
+    "We want to plot the solution `uh`. As the function space used to define the mesh is disconnected from the function space defining the mesh, we create a mesh based on the dof coordinates for the function space `V`. We use `dolfinx.plot.vtk_mesh` with the function space as input to create a mesh with mesh geometry based on the dof coordinates."
    ]
   },
   {
diff --git a/chapter1/membrane_code.ipynb b/chapter1/membrane_code.ipynb
index 9643260..03ed2fc 100644
--- a/chapter1/membrane_code.ipynb
+++ b/chapter1/membrane_code.ipynb
@@ -10,7 +10,7 @@
     "\n",
     "In this section, we will solve the deflection of the membrane problem.\n",
     "After finishing this section, you should be able to:\n",
-    "- Create a simple mesh using the GMSH Python API and load it into DOLFINx\n",
+    "- Create a simple mesh using the Gmsh Python API and load it into DOLFINx\n",
     "- Create constant boundary conditions using a geometrical identifier\n",
     "- Use `ufl.SpatialCoordinate` to create a spatially varying function\n",
     "- Interpolate a `ufl.Expression` into an appropriate function space\n",
@@ -19,7 +19,7 @@
     "\n",
     "## Creating the mesh\n",
     "\n",
-    "To create the computational geometry, we use the python-API of [GMSH](http://gmsh.info/). We start by importing the gmsh-module and initializing it."
+    "To create the computational geometry, we use the python-API of [Gmsh](http://gmsh.info/). We start by importing the gmsh-module and initializing it."
    ]
   },
   {
@@ -37,7 +37,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "The next step is to create the membrane and start the computations by the GMSH CAD kernel, to generate the relevant underlying data structures. The first arguments of `addDisk` are the x, y and z coordinate of the center of the circle, while the two last arguments are the x-radius and y-radius."
+    "The next step is to create the membrane and start the computations by the Gmsh CAD kernel, to generate the relevant underlying data structures. The first arguments of `addDisk` are the x, y and z coordinate of the center of the circle, while the two last arguments are the x-radius and y-radius."
    ]
   },
   {
@@ -84,7 +84,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Finally, we generate the two-dimensional mesh. We set a uniform mesh size by modifying the GMSH options."
+    "Finally, we generate the two-dimensional mesh. We set a uniform mesh size by modifying the Gmsh options."
    ]
   },
   {
@@ -117,8 +117,8 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "# Interfacing with GMSH in DOLFINx\n",
-    "We will import the GMSH-mesh directly from GMSH into DOLFINx via the `dolfinx.io.gmshio` interface.\n",
+    "# Interfacing with Gmsh in DOLFINx\n",
+    "We will import the Gmsh-mesh directly from Gmsh into DOLFINx via the `dolfinx.io.gmshio` interface.\n",
     "As in this example, we have not specified which process we have created the `gmsh` model on, a model has been created on each mpi process. However, we would like to be able to use a mesh distributed over all processes. Therefore, we take the model generated on rank 0 of `MPI.COMM_WORLD`, and distribute it over all available ranks. We will also get two mesh tags, one for cells marked with physical groups in the mesh and one for facets marked with physical groups. As we did not add any physical groups of dimension `gdim-1`, there will be no entities in the `facet_markers`."
    ]
   },
diff --git a/chapter1/membrane_code.py b/chapter1/membrane_code.py
index 13c8781..26a83b7 100644
--- a/chapter1/membrane_code.py
+++ b/chapter1/membrane_code.py
@@ -18,7 +18,7 @@
 #
 # In this section, we will solve the deflection of the membrane problem.
 # After finishing this section, you should be able to:
-# - Create a simple mesh using the GMSH Python API and load it into DOLFINx
+# - Create a simple mesh using the Gmsh Python API and load it into DOLFINx
 # - Create constant boundary conditions using a geometrical identifier
 # - Use `ufl.SpatialCoordinate` to create a spatially varying function
 # - Interpolate a `ufl.Expression` into an appropriate function space
@@ -27,12 +27,12 @@
 #
 # ## Creating the mesh
 #
-# To create the computational geometry, we use the python-API of [GMSH](http://gmsh.info/). We start by importing the gmsh-module and initializing it.
+# To create the computational geometry, we use the python-API of [Gmsh](http://gmsh.info/). We start by importing the gmsh-module and initializing it.
 
 import gmsh
 gmsh.initialize()
 
-# The next step is to create the membrane and start the computations by the GMSH CAD kernel, to generate the relevant underlying data structures. The first arguments of `addDisk` are the x, y and z coordinate of the center of the circle, while the two last arguments are the x-radius and y-radius.
+# The next step is to create the membrane and start the computations by the Gmsh CAD kernel, to generate the relevant underlying data structures. The first arguments of `addDisk` are the x, y and z coordinate of the center of the circle, while the two last arguments are the x-radius and y-radius.
 
 membrane = gmsh.model.occ.addDisk(0, 0, 0, 1, 1)
 gmsh.model.occ.synchronize()
@@ -42,14 +42,14 @@ gmsh.model.occ.synchronize()
 gdim = 2
 gmsh.model.addPhysicalGroup(gdim, [membrane], 1)
 
-# Finally, we generate the two-dimensional mesh. We set a uniform mesh size by modifying the GMSH options.
+# Finally, we generate the two-dimensional mesh. We set a uniform mesh size by modifying the Gmsh options.
 
 gmsh.option.setNumber("Mesh.CharacteristicLengthMin", 0.05)
 gmsh.option.setNumber("Mesh.CharacteristicLengthMax", 0.05)
 gmsh.model.mesh.generate(gdim)
 
-# # Interfacing with GMSH in DOLFINx
-# We will import the GMSH-mesh directly from GMSH into DOLFINx via the `dolfinx.io.gmshio` interface.
+# # Interfacing with Gmsh in DOLFINx
+# We will import the Gmsh-mesh directly from Gmsh into DOLFINx via the `dolfinx.io.gmshio` interface.
 # As in this example, we have not specified which process we have created the `gmsh` model on, a model has been created on each mpi process. However, we would like to be able to use a mesh distributed over all processes. Therefore, we take the model generated on rank 0 of `MPI.COMM_WORLD`, and distribute it over all available ranks. We will also get two mesh tags, one for cells marked with physical groups in the mesh and one for facets marked with physical groups. As we did not add any physical groups of dimension `gdim-1`, there will be no entities in the `facet_markers`.
 
 # +
diff --git a/chapter2/elasticity_scaling.md b/chapter2/elasticity_scaling.md
index da15c47..5672744 100644
--- a/chapter2/elasticity_scaling.md
+++ b/chapter2/elasticity_scaling.md
@@ -18,6 +18,6 @@ where $\beta = 1+\frac{\lambda}{\mu}$ is a dimensionless elasticity parameter an
 ```
 is a dimensionless variable reflecting the ratio of the load $\rho g$ and the shear stress term $\mu \nabla^2u \sim \mu \frac{U}{L^2}$ in the PDE.
 
-One option for the scaling is to chose $U$ such that $\gamma$ is of unit size ($U=\frac{\rho g L^2}{\mu}$). However, in elasticity, this leads to displacements of the size of the geometry. This can be achieved by choosing $U$ equal to the maximum deflection of a clamped beam, for which there actually exists a formula: $U=\frac{3}{2} \rho g L^2\frac{\delta^2}{E}$ where $\delta=\frac{L}{W}$ is a parameter reflecting how slender the beam is, and $E$ is the modulus of elasticity. Thus the dimensionless parameter $\delta$ is very important in the problem (as expected $\delta\gg 1$ is what gives beam theory!). Taking $E$ to be of the same order as $\mu$, which in this case and for many materials, we realize that $\gamma \sim \delta^{-2}$ is an appropriate choice. Experimenting with the code to find a displacement that "looks right" in the plots of the deformed geometry, points to $\gamma=0.4\delta^{-2}$ as our final choice of $\gamma$.
+One option for the scaling is to chose $U$ such that $\gamma$ is of unit size ($U=\frac{\rho g L^2}{\mu}$). However, in elasticity, this leads to displacements of the size of the geometry (and strange plots). This can be avoided by choosing $U$ equal to the maximum deflection of a clamped beam, for which there actually exists a formula: $U=\frac{3}{2} \rho g L^2\frac{\delta^2}{E}$ where $\delta=\frac{L}{W}$ is a parameter reflecting how slender the beam is, and $E$ is the modulus of elasticity. Thus the dimensionless parameter $\delta$ is very important in the problem (as expected $\delta\gg 1$ is what gives beam theory!). Taking $E$ to be of the same order as $\mu$, which is the case here and for many materials, we realize that $\gamma \sim \delta^{-2}$ is an appropriate choice. Experimenting with the code to find a displacement that "looks right" in the plots of the deformed geometry, points to $\gamma=0.4\delta^{-2}$ as our final choice of $\gamma$.
 
-The simulation code implements the problem with dimensions and physical parameters $\lambda, \mu, \rho, g, L$ and $W$. However, we can easily reuse this code for a scaled problem: Just set $\mu=\rho=L=1$, $W$ as $W/L(\delta^{-1})$, $g=\gamma$ and $\lambda=\beta$.
\ No newline at end of file
+The simulation code implements the problem with dimensions and physical parameters $\lambda, \mu, \rho, g, L$ and $W$. However, we can easily reuse this code for a scaled problem: Just set $\mu=\rho=L=1$, $W$ as $W/L(\delta^{-1})$, $g=\gamma$ and $\lambda=\beta$.
diff --git a/chapter2/heat_equation.md b/chapter2/heat_equation.md
index f66e03c..e35b81b 100644
--- a/chapter2/heat_equation.md
+++ b/chapter2/heat_equation.md
@@ -64,4 +64,4 @@ When solving this variational problem $u^0$ becomes the $L^2$-projection of the
 
 The alternative is to construct $u^0$ by just interpolating the initial value $u_0$. We covered how to use interpolation in DOLFINx in the {doc}`membrane chapter <../chapter1/membrane_code>`.
 
-We can use DOLFINx to either project or interpolate the initial condition. The most common choice is to use an projection, which computes an approximation to $u_0$. However, in some applications where we want to verify the code by reproducing exact solutions, one must use interpolate. In this chapter, we will use such a problem.
+We can use DOLFINx to either project or interpolate the initial condition. The most common choice is to use a projection, which computes an approximation to $u_0$. However, in some applications where we want to verify the code by reproducing exact solutions, one must use interpolate. In this chapter, we will use such a problem.


continues in next post

continued from last post



diff --git a/chapter2/linearelasticity_code.ipynb b/chapter2/linearelasticity_code.ipynb
index c07e0a9..74acb91 100644
--- a/chapter2/linearelasticity_code.ipynb
+++ b/chapter2/linearelasticity_code.ipynb
@@ -14,7 +14,7 @@
     "- Compute Von Mises stresses\n",
     "\n",
     "## Test problem\n",
-    "As a test example, we will model a clamped beam deformed under its own weigth in 3D. This can be modeled, by setting the right-hand side body force per unit volume to $f=(0,0,-\\rho g)$ with $\\rho$ the density of the beam and $g$ the acceleration of gravity. The beam is box-shaped with length $L$ and has a square cross section of width $W$. we set $u=u_D=(0,0,0)$ at the clamped end, x=0. The rest of the boundary is traction free, that is, we set $T=0$. We start by defining the physical variables used in the program."
+    "As a test example, we will model a clamped beam deformed under its own weight in 3D. This can be modeled, by setting the right-hand side body force per unit volume to $f=(0,0,-\\rho g)$ with $\\rho$ the density of the beam and $g$ the acceleration of gravity. The beam is box-shaped with length $L$ and has a square cross section of width $W$. we set $u=u_D=(0,0,0)$ at the clamped end, $x=0$. The rest of the boundary is traction free, that is, we set $T=0$. We start by defining the physical variables used in the program."
    ]
   },
   {
@@ -47,8 +47,8 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "We then create the mesh, which will consist of hexahedral elements, along with the function space. We will use the convenience function `VectorFunctionSpace`. However, we also could have used `ufl`s functionality, creating a vector element `element = ufl.VectorElement(\"Lagrange\", mesh.ufl_cell(), 1)\n",
-    "`, and intitializing the function space as `V = dolfinx.fem.FunctionSpace(mesh, element)`."
+    "We then create the mesh, which will consist of hexahedral elements, along with the function space. We will use the convenience that `FunctionSpace` provides. An alternative which uses `ufl`'s functionality would be to create a vector element `element = basix.ufl.element(\"Lagrange\", basix.CellType.hexahedron, 1)`\n",
+    ", and intitializing the function space as `V = dolfinx.fem.FunctionSpace(domain, element)`."
    ]
   },
   {
@@ -59,9 +59,10 @@
    },
    "outputs": [],
    "source": [
-    "domain = mesh.create_box(MPI.COMM_WORLD, [np.array([0, 0, 0]), np.array([L, W, W])],\n",
-    "                         [20, 6, 6], cell_type=mesh.CellType.hexahedron)\n",
-    "V = fem.VectorFunctionSpace(domain, (\"Lagrange\", 1))"
+    "domain = mesh.create_box(\n",
+    "    MPI.COMM_WORLD, [np.array([0, 0, 0]), np.array([L, W, W])],\n",
+    "    [20, 6, 6], cell_type=mesh.CellType.hexahedron)\n",
+    "V = fem.FunctionSpace(domain, (\"Lagrange\", 1, (domain.geometry.dim,)))"
    ]
   },
   {
@@ -69,7 +70,7 @@
    "metadata": {},
    "source": [
     "## Boundary conditions\n",
-    "As we would like to clamp the boundary at $x=0$, we do this by using a marker function, which locate the facets where $x$ is close to zero by machine prescision."
+    "As we would like to clamp the boundary at $x=0$, we do this by using a marker function, which locates the facets where $x$ is close to zero by machine prescision."
    ]
   },
   {
@@ -159,8 +160,8 @@
     "`div` and `grad`. This is because for scalar functions $\\nabla u$ has a clear meaning\n",
     "$\\nabla u = \\left(\\frac{\\partial u}{\\partial x}, \\frac{\\partial u}{\\partial y}, \\frac{\\partial u}{\\partial z} \\right)$.\n",
     "\n",
-    "However, if $u$ is vector valued, the meaning is less clear. Some sources define $\\nabla u$ as a matrix with the elements $\\frac{\\partial u_j}{\\partial x_i}$, while other  sources prefer\n",
-    "$\\frac{\\partial u_i}{\\partial x_j}$. In DOLFINx `grad(u)` is defined as the amtrix with element $\\frac{\\partial u_i}{\\partial x_j}$. However, as it is common in continuum mechanics to use the other definition, `ufl` supplies us with `nabla_grad` for this purpose.\n",
+    "However, if $u$ is vector valued, the meaning is less clear. Some sources define $\\nabla u$ as a matrix with the elements $\\frac{\\partial u_j}{\\partial x_i}$, while other  sources prefer \n",
+    "$\\frac{\\partial u_i}{\\partial x_j}$. In DOLFINx `grad(u)` is defined as the matrix with element $\\frac{\\partial u_i}{\\partial x_j}$. However, as it is common in continuum mechanics to use the other definition, `ufl` supplies us with `nabla_grad` for this purpose.\n",
     "```\n",
     "\n",
     "## Solve the linear variational problem\n",
diff --git a/chapter2/nonlinpoisson_code.ipynb b/chapter2/nonlinpoisson_code.ipynb
index 1263b98..e16bc58 100644
--- a/chapter2/nonlinpoisson_code.ipynb
+++ b/chapter2/nonlinpoisson_code.ipynb
@@ -77,7 +77,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "We are now ready to define the variational formulation. Note that as the problem is non-linear, we have replace the `TrialFunction` with a `Function`, which serves as the unknown of our problem."
+    "We are now ready to define the variational formulation. Note that as the problem is non-linear, we have to replace the `TrialFunction` with a `Function`, which serves as the unknown of our problem."
    ]
   },
   {
diff --git a/chapter2/ns_code2.ipynb b/chapter2/ns_code2.ipynb
index 8bfcb22..45017ec 100644
--- a/chapter2/ns_code2.ipynb
+++ b/chapter2/ns_code2.ipynb
@@ -29,7 +29,7 @@
     "\n",
     "which has a maximum magnitude of $1.5$ at $y=0.41/2$. We do not use any scaling for this problem since all exact parameters are known.\n",
     "## Mesh generation\n",
-    "As in the [Deflection of a membrane](./../chapter1/membrane_code.ipynb) we use GMSH to generate the mesh. We fist create the rectangle and obstacle."
+    "As in the [Deflection of a membrane](./../chapter1/membrane_code.ipynb) we use Gmsh to generate the mesh. We fist create the rectangle and obstacle."
    ]
   },
   {
@@ -107,7 +107,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "To get GMSH to mesh the fluid, we add a physical volume marker"
+    "To get Gmsh to mesh the fluid, we add a physical volume marker"
    ]
   },
   {
@@ -165,7 +165,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "In our previous meshes, we have used uniform mesh sizes. In this example, we will have variable mesh sizes to resolve the flow solution in  the area of interest; close to the circular obstacle. To do this, we use GMSH Fields."
+    "In our previous meshes, we have used uniform mesh sizes. In this example, we will have variable mesh sizes to resolve the flow solution in  the area of interest; close to the circular obstacle. To do this, we use Gmsh Fields."
    ]
   },
   {
@@ -266,7 +266,7 @@
    "source": [
     "## Loading mesh and boundary markers\n",
     "As we have generated the mesh, we now need to load the mesh and corresponding facet markers into DOLFINx.\n",
-    "To load the mesh, we follow the same structure as in  [Deflection of a membrane](./../chapter1/membrane_code.ipynb), with the difference being that we will load in facet markers as well. To learn more about the specifics of the function below, see [A GMSH tutorial for DOLFINx](https://jsdokken.com/src/tutorial_gmsh.html)."
+    "To load the mesh, we follow the same structure as in  [Deflection of a membrane](./../chapter1/membrane_code.ipynb), with the difference being that we will load in facet markers as well. To learn more about the specifics of the function below, see [A Gmsh tutorial for DOLFINx](https://jsdokken.com/src/tutorial_gmsh.html)."
    ]
   },
   {
diff --git a/chapter2/ns_code2.py b/chapter2/ns_code2.py
index dfa8ae3..80cc4f7 100644
--- a/chapter2/ns_code2.py
+++ b/chapter2/ns_code2.py
@@ -38,7 +38,7 @@
 #
 # which has a maximum magnitude of $1.5$ at $y=0.41/2$. We do not use any scaling for this problem since all exact parameters are known.
 # ## Mesh generation
-# As in the [Deflection of a membrane](./../chapter1/membrane_code.ipynb) we use GMSH to generate the mesh. We fist create the rectangle and obstacle.
+# As in the [Deflection of a membrane](./../chapter1/membrane_code.ipynb) we use Gmsh to generate the mesh. We fist create the rectangle and obstacle.
 
 # +
 import gmsh
@@ -83,7 +83,7 @@ if mesh_comm.rank == model_rank:
     fluid = gmsh.model.occ.cut([(gdim, rectangle)], [(gdim, obstacle)])
     gmsh.model.occ.synchronize()
 
-# To get GMSH to mesh the fluid, we add a physical volume marker
+# To get Gmsh to mesh the fluid, we add a physical volume marker
 
 fluid_marker = 1
 if mesh_comm.rank == model_rank:
@@ -117,7 +117,7 @@ if mesh_comm.rank == model_rank:
     gmsh.model.addPhysicalGroup(1, obstacle, obstacle_marker)
     gmsh.model.setPhysicalName(1, obstacle_marker, "Obstacle")
 
-# In our previous meshes, we have used uniform mesh sizes. In this example, we will have variable mesh sizes to resolve the flow solution in  the area of interest; close to the circular obstacle. To do this, we use GMSH Fields.
+# In our previous meshes, we have used uniform mesh sizes. In this example, we will have variable mesh sizes to resolve the flow solution in  the area of interest; close to the circular obstacle. To do this, we use Gmsh Fields.
 
 # Create distance field from obstacle.
 # Add threshold of mesh sizes based on the distance field
@@ -154,7 +154,7 @@ if mesh_comm.rank == model_rank:
 
 # ## Loading mesh and boundary markers
 # As we have generated the mesh, we now need to load the mesh and corresponding facet markers into DOLFINx.
-# To load the mesh, we follow the same structure as in  [Deflection of a membrane](./../chapter1/membrane_code.ipynb), with the difference being that we will load in facet markers as well. To learn more about the specifics of the function below, see [A GMSH tutorial for DOLFINx](https://jsdokken.com/src/tutorial_gmsh.html).
+# To load the mesh, we follow the same structure as in  [Deflection of a membrane](./../chapter1/membrane_code.ipynb), with the difference being that we will load in facet markers as well. To learn more about the specifics of the function below, see [A Gmsh tutorial for DOLFINx](https://jsdokken.com/src/tutorial_gmsh.html).
 
 mesh, _, ft = gmshio.model_to_mesh(gmsh.model, mesh_comm, model_rank, gdim=gdim)
 ft.name = "Facet markers"
diff --git a/chapter3/subdomains.ipynb b/chapter3/subdomains.ipynb
index c1e42bc..b938d92 100644
--- a/chapter3/subdomains.ipynb
+++ b/chapter3/subdomains.ipynb
@@ -68,7 +68,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Note that both fucntion uses a $\\leq$ or $\\geq$, as FEniCSx will evaluate each cell at all of the vertices, and thus for has to return `True` for all vertices align with the interface to be marked properly.\n",
+    "Note that both functions use a $\\leq$ or $\\geq$, as FEniCSx will evaluate each cell at all of the vertices, and thus for has to return `True` for all vertices align with the interface to be marked properly.\n",
     "\n",
     "We will solve a variable-coefficient extension of the Poisson equation\n",
     "\n",
@@ -220,7 +220,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "We clearly observe different behavior in the two regions, whose both has the same Dirichlet boundary condition on the left side, where $x=0$."
+    "We clearly observe different behavior in the two regions, both of which have the same Dirichlet boundary condition on the left side, where $x=0$."
    ]
   },
   {
@@ -289,7 +289,7 @@
    "metadata": {},
    "source": [
     "## Subdomains defined from external mesh data\n",
-    "Let us now consider the same problem, but using GMSH to generate the mesh and subdomains. We will then in turn show how to use this data to generate discontinuous functions in DOLFINx."
+    "Let us now consider the same problem, but using Gmsh to generate the mesh and subdomains. We will then in turn show how to use this data to generate discontinuous functions in DOLFINx."
    ]
   },
   {
@@ -507,7 +507,6 @@
    "outputs": [],
    "source": [
     "V = FunctionSpace(mesh, (\"Lagrange\", 1))\n",
-    "u_bc = Function(V)\n",
     "left_facets = ft.find(left_marker)\n",
     "left_dofs = locate_dofs_topological(V, mesh.topology.dim - 1, left_facets)\n",
     "bcs = [dirichletbc(default_scalar_type(1), left_dofs, V)]"
diff --git a/chapter3/subdomains.py b/chapter3/subdomains.py
index 35afb9c..5eb4fe3 100644
--- a/chapter3/subdomains.py
+++ b/chapter3/subdomains.py
@@ -61,7 +61,7 @@ def Omega_1(x):
 
 # -
 
-# Note that both fucntion uses a $\leq$ or $\geq$, as FEniCSx will evaluate each cell at all of the vertices, and thus for has to return `True` for all vertices align with the interface to be marked properly.
+# Note that both function use a $\leq$ or $\geq$, as FEniCSx will evaluate each cell at all of the vertices, and thus for has to return `True` for all vertices align with the interface to be marked properly.
 #
 # We will solve a variable-coefficient extension of the Poisson equation
 #
@@ -161,7 +161,7 @@ error = mesh.comm.allreduce(assemble_scalar(form((kappa - kappa2)**2 * dx)))
 print(error)
 
 # ## Subdomains defined from external mesh data
-# Let us now consider the same problem, but using GMSH to generate the mesh and subdomains. We will then in turn show how to use this data to generate discontinuous functions in DOLFINx.
+# Let us now consider the same problem, but using Gmsh to generate the mesh and subdomains. We will then in turn show how to use this data to generate discontinuous functions in DOLFINx.
 
 gmsh.initialize()
 proc = MPI.COMM_WORLD.rank
-- 
2.42.0