Skip to content
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
28 changes: 16 additions & 12 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@

## v0.9.0

- `scale` in `apply_lifting` has been renamed to `alpha`
- `scale` in {py:func}`apply_lifting<dolfinx.fem.petsc.apply_lifting>` has been renamed to `alpha`
- Use `dolfinx.fem.Function.x.petsc_vec` as opposed to `dolfinx.fem.Function.vector`

## v0.8.0

- Replace all `ufl.FiniteElement` and `ufl.VectorElement` with the appropriate `basix.ufl.element`
- Replace `dolfinx.fem.FunctionSpace` with `dolfinx.fem.functionspace`
- Replace all `ufl.FiniteElement` and `ufl.VectorElement` with the appropriate {py:func}`basix.ufl.element`
- Replace {py:class}`dolfinx.fem.FunctionSpace` with {py:func}`dolfinx.fem.functionspace`

## v0.7.2

Expand All @@ -31,12 +31,13 @@

## 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`
- Renamed `dolfinx.graph.create_adjacencylist` to {py:func}`dolfinx.graph.adjacencylist`
- Renamed `dolfinx.plot.create_vtk_mesh` to {py:func}`dolfinx.plot.vtk_mesh`
- Initialization of {py:class}`dolfinx.geometry.BoundingBoxTree` has been changed to {py:func}`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.

- Update dolfinx petsc API. Now one needs to explicitly import {py:mod}`dolfinx.fem.petsc` and {py:mod}`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 {py:mod}`petsc4py` explicitly.

## v0.6.0

- Remove `ipygany` and `pythreejs` as plotting backends. Using `panel`.
Expand All @@ -50,7 +51,8 @@

- 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 minor DOLFINx API updates. `dolfinx.mesh.compute_boundary_facets` -> {py:func}`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`.
- Change all notebooks to use [jupytext](https://jupytext.readthedocs.io/en/latest/install.html) to automatically sync `.ipynb` with `.py` files.
- Add example of how to use `DOLFINx` in complex mode, see [chapter1/complex_mode].
Expand All @@ -62,11 +64,13 @@
## 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.plot.create_vtk_topology` has been renamed to `dolfinx.plot.create_vtk_mesh` and can now be directly used as input
to {py:class}`pyvista.UnstructuredGrid`.
- `dolfinx.fem.Function.compute_point_values` has been deprecated. Interpolation into a CG-1 is now the way of getting vertex values.
- API updates wrt. DOLFINx. `Form`->`form`, `DirichletBC`->`dirichletbc`.
- Instead of initializing class with {py:class}`Form<dolfinx.fem.Form>`, use {py:func}`form<dolfinx.fem.form>`.
- Instead of initializing class with {py:class}`DirichletBC<dolfinx.fem.DirichletBC>` use {py:func}`dirichletbc<dolfinx.fem.dirichletbc>`.
- 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 interpolation of {py:class}`ufl.core.expr.Expr` in [Deflection of a membrane](chapter1/membrane_code).
- Added tutorial on how to apply constant-valued Dirichlet conditions in [Deflection of a membrane](chapter1/membrane_code).
- Various API changes relating to the import structure of DOLFINx

Expand Down
77 changes: 59 additions & 18 deletions chapter1/complex_mode.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,58 @@
"\n",
"Author: Jørgen S. Dokken\n",
"\n",
"Many PDEs, such as the [Helmholtz equation](https://docs.fenicsproject.org/dolfinx/v0.4.1/python/demos/demo_helmholtz.html) require complex-valued fields.\n",
"Many PDEs, such as the [Helmholtz equation](https://docs.fenicsproject.org/dolfinx/main/python/demos/demo_helmholtz.html)\n",
"require complex-valued fields.\n",
"\n",
"For simplicity, let us consider a Poisson equation of the form:\n",
"\n",
"$$-\\Delta u = f \\text{ in } \\Omega,$$\n",
"$$ f = -1 - 2j \\text{ in } \\Omega,$$\n",
"$$ u = u_{exact} \\text{ on } \\partial\\Omega,$$\n",
"$$u_{exact}(x, y) = \\frac{1}{2}x^2 + 1j\\cdot y^2,$$\n",
"$$\n",
"\\begin{align}\n",
"-\\Delta u &= f &&\\text{in } \\Omega,\\\\\n",
"f &= -1 - 2j &&\\text{in } \\Omega,\\\\\n",
"u &= u_{exact} &&\\text{on } \\partial\\Omega,\\\\\n",
"u_{exact}(x, y) &= \\frac{1}{2}x^2 + 1j\\cdot y^2,\n",
"\\end{align}\n",
"$$\n",
"\n",
"As in [Solving the Poisson equation](./fundamentals) we want to express our partial differential equation as a weak formulation.\n",
"As in [Solving the Poisson equation](./fundamentals) we want to express our partial differential equation\n",
"as a weak formulation.\n",
"\n",
"We start by defining our discrete function space $V_h$, such that $u_h\\in V_h$ and $u_h = \\sum_{i=1}^N c_i \\phi_i(x, y)$ where $\\phi_i$ are **real valued** global basis functions of our space $V_h$, and $c_i \\in \\mathcal{C}$ are the **complex valued** degrees of freedom.\n",
"We start by defining our discrete function space $V_h$, such that $u_h\\in V_h$ and\n",
"$u_h = \\sum_{i=1}^N c_i \\phi_i(x, y)$ where $\\phi_i$ are **real valued** global basis\n",
"functions of our space $V_h$, and $c_i \\in \\mathcal{C}$ are the **complex valued** degrees of freedom.\n",
"\n",
"Next, we choose a test function $v\\in \\hat V_h$ where $\\hat V_h\\subset V_h$ such that $v\\vert_{\\partial\\Omega}=0$, as done in the first tutorial.\n",
"We now need to define our inner product space. We choose the $L^2$ inner product spaces, which is a _[sesquilinear](https://en.wikipedia.org/wiki/Sesquilinear_form) 2-form_, meaning that $\\langle u, v\\rangle$ is a map from $V_h\\times V_h\\mapsto K$, and $\\langle u, v \\rangle = \\int_\\Omega u \\cdot \\bar v ~\\mathrm{d} x$. As it is sesquilinear, we have the following properties:\n",
"Next, we choose a test function $v\\in \\hat V_h$ where $\\hat V_h\\subset V_h$ such that $v\\vert_{\\partial\\Omega}=0$, as done in the [first tutorial](./fundamentals).\n",
"We now need to define our inner product space.\n",
"We choose the $L^2$ inner product spaces, which is a _[sesquilinear](https://en.wikipedia.org/wiki/Sesquilinear_form) 2-form_,\n",
"meaning that $\\langle u, v\\rangle$ is a map from $V_h\\times V_h\\mapsto K$, and\n",
"$\\langle u, v \\rangle = \\int_\\Omega u \\cdot \\bar v ~\\mathrm{d} x$. As it is sesquilinear, we have the following properties:\n",
"\n",
"$$\\langle u , v \\rangle = \\overline{\\langle v, u \\rangle},$$\n",
"$$\\langle u , u \\rangle \\geq 0.$$\n",
"$$\n",
"\\begin{align}\n",
"\\langle u , v \\rangle &= \\overline{\\langle v, u \\rangle},\\\\\n",
"\\langle u , u \\rangle &\\geq 0.\n",
"\\end{align}\n",
"$$\n",
"\n",
"We can now use this inner product space to do integration by parts\n",
"\n",
"$$\\int_\\Omega \\nabla u_h \\cdot \\nabla \\overline{v}~ \\mathrm{dx} = \\int_{\\Omega} f \\cdot \\overline{v} ~\\mathrm{d} s \\qquad \\forall v \\in \\hat{V}_h.$$\n",
"$$\n",
"\\int_\\Omega \\nabla u_h \\cdot \\nabla \\overline{v}~\\mathrm{dx} =\n",
"\\int_{\\Omega} f \\cdot \\overline{v} ~\\mathrm{d} s \\qquad \\forall v \\in \\hat{V}_h.\n",
"$$\n",
"\n",
"## Installation of FEniCSx with complex number support\n",
"\n",
"FEniCSx supports both real and complex numbers, so we can create a function space with real valued or complex valued coefficients.\n"
"FEniCSx supports both real and complex numbers, so we can create a {py:class}`function space <dolfinx.fem.FunctionSpace>`\n",
"with either real valued or complex valued coefficients.\n",
"```{admonition} Function or Coefficient\n",
"In FEniCSx, the term *function* and *coefficient* are used interchangeably.\n",
"A function is a linear combination of basis functions with coefficients, and the coefficients can be real or complex numbers.\n",
"In {py:mod}`ufl`, the term {py:class}`Coefficient <ufl.Coefficient>`, while in {py:mod}`dolfinx` we use {py:class}`Function<dolfinx.fem.Function>`\n",
"to represent the same concept (through inheritance). This is because most people think of finding the **unknown** function that solves a PDE,\n",
"while the coefficients are the set of values that define the function.\n",
"```"
]
},
{
Expand Down Expand Up @@ -63,9 +89,16 @@
"id": "2",
"metadata": {},
"source": [
"However, as we would like to solve linear algebra problems of the form $Ax=b$, we need to be able to use matrices and vectors that support real and complex numbers. As [PETSc](https://petsc.org/release/) is one of the most popular interfaces to linear algebra packages, we need to be able to work with their matrix and vector structures.\n",
"However, as we would like to solve linear algebra problems of the form $Ax=b$, we need to be able to use matrices and vectors that support real and complex numbers.\n",
"As {[PETSc](https://petsc.org/release/)} is the most popular interfaces to linear algebra packages, we need to be able to work with their matrix and vector structures.\n",
"\n",
"Unfortunately, PETSc only supports one floating type in their matrices, thus we need to install two versions of PETSc, one that supports `float64` and one that supports `complex128`. In the [docker images](https://hub.docker.com/r/dolfinx/dolfinx) for DOLFINx, both versions are installed, and one can switch between them by calling `source dolfinx-real-mode` or `source dolfinx-complex-mode`. For the `dolfinx/lab` images, one can change the Python kernel to be either the real or complex mode, by going to `Kernel->Change Kernel...` and choosing `Python3 (ipykernel)` (for real mode) or `Python3 (DOLFINx complex)` (for complex mode).\n",
"Unfortunately, PETSc only supports one floating type in their matrices, thus we need to install two versions of PETSc,\n",
"one that supports `float64` and one that supports `complex128`.\n",
"In the [Docker images]https://github.com/orgs/FEniCS/packages/container/package/dolfinx%2Fdolfinx) for DOLFINx, both versions are installed,\n",
"and one can switch between them by calling `source dolfinx-real-mode` or `source dolfinx-complex-mode`.\n",
"For the [dolfinx/lab](https://github.com/FEniCS/dolfinx/pkgs/container/dolfinx%2Flab) images,\n",
"one can change the Python kernel to be either the real or complex mode, by going to\n",
"`Kernel->Change Kernel...` and choosing `Python3 (ipykernel)` (for real mode) or `Python3 (DOLFINx complex)` (for complex mode).\n",
"\n",
"We check that we are using the correct installation of PETSc by inspecting the scalar type."
]
Expand Down Expand Up @@ -114,9 +147,14 @@
"id": "6",
"metadata": {},
"source": [
"Note that we have used the `PETSc.ScalarType` to wrap the constant source on the right hand side. This is because we want the integration kernels to assemble into the correct floating type.\n",
"Note that we have used the `PETSc.ScalarType` to wrap the constant source on the right hand side.\n",
"This is because we want the integration kernels to assemble into the correct floating type.\n",
"\n",
"Secondly, note that we are using `ufl.inner` to describe multiplication of $f$ and $v$, even if they are scalar values. This is because `ufl.inner` takes the conjugate of the second argument, as decribed by the $L^2$ inner product. One could alternatively write this out explicitly\n",
"Secondly, note that we are using {py:func}`ufl.inner` to describe multiplication of $f$ and $v$,\n",
"even if they are scalar values.\n",
"This is because {py:func}`ufl.inner` takes the conjugate of the second argument,\n",
"as decribed by the $L^2$ inner product.\n",
"One could alternatively write this out explicitly\n",
"\n",
"### Inner-products and derivatives"
]
Expand All @@ -138,7 +176,10 @@
"id": "8",
"metadata": {},
"source": [
"Similarly, if we want to use the function `ufl.derivative` to take derivatives of functionals, we need to take some special care. As `ufl.derivative` inserts a `ufl.TestFunction` to represent the variation, we need to take the conjugate of this to be able to use it to assemble vectors.\n"
"Similarly, if we want to use the function {py:func}`ufl.derivative` to take derivatives of functionals,\n",
"we need to take some special care.\n",
"As {py:func}`ufl.derivative` inserts a {py:func}`ufl.TestFunction` to represent the variation,\n",
"we need to take the conjugate of this to be able to use it to assemble vectors."
]
},
{
Expand Down
Loading