From 1f49c83493f6b9d1626b8e82efc8ac38a213acd7 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 2 Jul 2026 18:54:24 +0200 Subject: [PATCH 01/19] Run mypy on demos --- .github/workflows/ccpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index a3c1070b66..08cd0b7a73 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -138,7 +138,7 @@ jobs: mypy --config-file python/pyproject.toml -p dolfinx # package mode, type checks installed dolfinx (working around name collision in python/ directory) cd python/ mypy test - #mypy demo # TODO: Enable this in future + mypy demo - name: Install gmsh and pyvista (and dependencies) run: | From a58c7f779deb527d092ec729cb70225ea995bfff Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 2 Jul 2026 18:54:43 +0200 Subject: [PATCH 02/19] TMP: run CI --- .github/workflows/ccpp.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 08cd0b7a73..f1e4bed74b 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -2,11 +2,11 @@ name: CI on: push: - branches: - - main - - release - tags: - - "v*" + # branches: + # - main + # - release + # tags: + # - "v*" pull_request: branches: - main From 6ad51906c00d8da1a2c9f2dd354be4c8dd5a19d7 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 13:16:35 +0200 Subject: [PATCH 03/19] Fix variable redaclaration --- python/demo/demo_mixed-topology.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/demo/demo_mixed-topology.py b/python/demo/demo_mixed-topology.py index f725b90465..9525c26a4f 100644 --- a/python/demo/demo_mixed-topology.py +++ b/python/demo/demo_mixed-topology.py @@ -193,7 +193,7 @@ def marker(x): A_scipy = A.to_scipy() b_scipy = b.array -x = spsolve(A_scipy, b_scipy) +x_scipy = spsolve(A_scipy, b_scipy) print(f"Solution vector norm {np.linalg.norm(x)}") @@ -235,8 +235,8 @@ def marker(x): - - {" ".join(str(val) for val in x)} + + {" ".join(str(val) for val in x_scipy)} """ From 5563300597fcea2bc6f51c1ba9e0cb90975ac136 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 13:25:14 +0200 Subject: [PATCH 04/19] Improve plotting type hints --- python/demo/demo_interpolation-io.py | 2 +- python/dolfinx/plot.py | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/python/demo/demo_interpolation-io.py b/python/demo/demo_interpolation-io.py index 0145691d96..5b30352855 100644 --- a/python/demo/demo_interpolation-io.py +++ b/python/demo/demo_interpolation-io.py @@ -119,7 +119,7 @@ pl.add_text("y-component", font_size=12, color="black", position="upper_edge") pl.add_mesh(grid.copy(), component=1, show_edges=True) - pl.view_xy() + pl.view_xy() # type: ignore pl.link_views() # If pyvista environment variable is set to off-screen (static) diff --git a/python/dolfinx/plot.py b/python/dolfinx/plot.py index 2f39658223..34b80a25af 100644 --- a/python/dolfinx/plot.py +++ b/python/dolfinx/plot.py @@ -6,8 +6,10 @@ """Support functions for plotting.""" import functools +from typing import overload import numpy as np +import numpy.typing as npt from dolfinx import cpp as _cpp from dolfinx import fem, mesh @@ -29,8 +31,18 @@ } +@overload +def vtk_mesh( + msh: mesh.Mesh, dim: int | None = None, entities: npt.NDArray[np.int32] | None = None +): ... + + +@overload +def vtk_mesh(V: fem.FunctionSpace, entities: npt.NDArray[np.int32] | None = None): ... + + @functools.singledispatch -def vtk_mesh(msh: mesh.Mesh, dim: int | None = None, entities=None): +def vtk_mesh(msh: mesh.Mesh, dim: int | None = None, entities: npt.NDArray[np.int32] | None = None): """Create VTK mesh topology data for mesh entities. The vertex indices in the returned topology array are the indices @@ -74,8 +86,8 @@ def vtk_mesh(msh: mesh.Mesh, dim: int | None = None, entities=None): return topology.reshape(-1), cell_types, msh.geometry.x -@vtk_mesh.register -def _(V: fem.FunctionSpace, entities=None): # type: ignore +@vtk_mesh.register # type: ignore[attr-defined] +def _(V: fem.FunctionSpace, entities: npt.NDArray[np.int32] | None = None): # type: ignore """Create VTK mesh topology based on the degree-of-freedom coordinates. This function supports visualisation when the degree of the finite @@ -113,7 +125,7 @@ def _(V: fem.FunctionSpace, entities=None): # type: ignore msh = V.mesh tdim = msh.topology.dim if entities is None: - entities = range(msh.topology.index_map(tdim).size_local) + entities = np.arange(msh.topology.index_map(tdim).size_local, dtype=np.int32) dofmap = V.dofmap num_dofs_per_cell = V.dofmap.dof_layout.num_dofs @@ -123,9 +135,9 @@ def _(V: fem.FunctionSpace, entities=None): # type: ignore vtk_type = ( _first_order_vtk[cell_type] if degree == 1 else _cpp.io.get_vtk_cell_type(cell_type, tdim) ) - cell_types = np.full(len(entities), vtk_type) + cell_types = np.full(entities.size, vtk_type) - topology = np.zeros((len(entities), num_dofs_per_cell + 1), dtype=np.int32) + topology = np.zeros((entities.size, num_dofs_per_cell + 1), dtype=np.int32) topology[:, 0] = num_dofs_per_cell dofmap_ = dofmap.list topology[:, 1:] = dofmap_[entities][:, perm] From ee2a1c31c3771e0eb3db8ce0d25b5aae2287c002 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:42:48 +0200 Subject: [PATCH 05/19] Exclude failing demos for now --- python/pyproject.toml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/pyproject.toml b/python/pyproject.toml index 9a2aededc0..046b2a9d11 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -103,6 +103,14 @@ warn_unused_ignores = false show_error_codes = true ignore_missing_imports = true +exclude = [ + "demo/demo_hdg.py", + "demo/demo_lagrange-variants.py", + "demo/demo_matrix-free-petsc.py", + "demo/demo_mixed-topology.py", + "demo/demo_navier-stokes.py", +] + [tool.ruff] line-length = 100 indent-width = 4 From cf428b7fa4381d1ddb813aa0f92c8f6b6043740e Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 15:25:39 +0200 Subject: [PATCH 06/19] more --- python/demo/demo_mixed-topology.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/demo/demo_mixed-topology.py b/python/demo/demo_mixed-topology.py index 9525c26a4f..f6a49cb71e 100644 --- a/python/demo/demo_mixed-topology.py +++ b/python/demo/demo_mixed-topology.py @@ -195,7 +195,7 @@ def marker(x): x_scipy = spsolve(A_scipy, b_scipy) -print(f"Solution vector norm {np.linalg.norm(x)}") +print(f"Solution vector norm {np.linalg.norm(x_scipy)}") # Mixed-topology I/O # We manually build a ASCII XDMF file to store the mesh From eb5fc46ce37a963e83310c7139f33100209be410 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 18:30:54 +0200 Subject: [PATCH 07/19] deactivate --- python/pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/pyproject.toml b/python/pyproject.toml index 046b2a9d11..7c356e7a1b 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -104,10 +104,10 @@ show_error_codes = true ignore_missing_imports = true exclude = [ - "demo/demo_hdg.py", + # "demo/demo_hdg.py", "demo/demo_lagrange-variants.py", - "demo/demo_matrix-free-petsc.py", - "demo/demo_mixed-topology.py", + # "demo/demo_matrix-free-petsc.py", + # "demo/demo_mixed-topology.py", "demo/demo_navier-stokes.py", ] From e94fe118a661b01a39688599d018d4d325838577 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 18:40:46 +0200 Subject: [PATCH 08/19] fix extract_function_spaces --- python/demo/demo_hdg.py | 4 ++-- python/dolfinx/fem/forms.py | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/python/demo/demo_hdg.py b/python/demo/demo_hdg.py index e8b5a77e7a..2634ffcc0a 100644 --- a/python/demo/demo_hdg.py +++ b/python/demo/demo_hdg.py @@ -98,8 +98,8 @@ def u_e(x): # Create the mesh -n = 8 # Number of elements in each direction -msh = mesh.create_unit_cube(comm, n, n, n, ghost_mode=mesh.GhostMode.none) +n_el = 8 # Number of elements in each direction +msh = mesh.create_unit_cube(comm, n_el, n_el, n_el, ghost_mode=mesh.GhostMode.none) # We need to create a broken Lagrange space defined over the facets of # the mesh. To do so, we require a sub-mesh of the all facets. We begin diff --git a/python/dolfinx/fem/forms.py b/python/dolfinx/fem/forms.py index 96513d9cc3..26037554fa 100644 --- a/python/dolfinx/fem/forms.py +++ b/python/dolfinx/fem/forms.py @@ -476,10 +476,23 @@ def _create_form(form): return _create_form(form) +@typing.overload +def extract_function_spaces(forms: Form, index: int = 0) -> FunctionSpace | None: ... + + +@typing.overload def extract_function_spaces( - forms: Form | Sequence[Form] | Sequence[Sequence[Form]], - index: int = 0, -) -> FunctionSpace | list[None | FunctionSpace]: + forms: Sequence[Form], index: int = 0 +) -> list[FunctionSpace | None]: ... + + +@typing.overload +def extract_function_spaces( + forms: Sequence[Sequence[Form]], index: int = 0 +) -> list[list[FunctionSpace | None]]: ... + + +def extract_function_spaces(forms, index: int = 0): """Extract common function spaces from an array of forms. If ``forms`` is a list of linear forms, this function returns of list From c9daa336fa978b85e395c89be3c20c02ea000d4c Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 18:41:37 +0200 Subject: [PATCH 09/19] test more --- python/pyproject.toml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/python/pyproject.toml b/python/pyproject.toml index 7c356e7a1b..00952b728f 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -104,11 +104,8 @@ show_error_codes = true ignore_missing_imports = true exclude = [ - # "demo/demo_hdg.py", - "demo/demo_lagrange-variants.py", - # "demo/demo_matrix-free-petsc.py", - # "demo/demo_mixed-topology.py", - "demo/demo_navier-stokes.py", + # "demo/demo_lagrange-variants.py", + # "demo/demo_navier-stokes.py", ] [tool.ruff] From 5dce56fc1a62fc46a1c7834c5a5a3cf4aebcab50 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 18:43:06 +0200 Subject: [PATCH 10/19] more --- python/dolfinx/fem/petsc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/dolfinx/fem/petsc.py b/python/dolfinx/fem/petsc.py index 5d1e0428c3..e85c768b7e 100644 --- a/python/dolfinx/fem/petsc.py +++ b/python/dolfinx/fem/petsc.py @@ -456,10 +456,10 @@ def _( "Cannot have a entire {'row' if index == 0 else 'column'} of a full of None" ) is0 = _cpp.la.petsc.create_index_sets( - [(Vsub.dofmaps[0].index_map, Vsub.dofmaps[0].index_map_bs) for Vsub in V[0]] # type: ignore[union-attr] + [(Vsub.dofmaps[0].index_map, Vsub.dofmaps[0].index_map_bs) for Vsub in V[0]] # type: ignore ) is1 = _cpp.la.petsc.create_index_sets( - [(Vsub.dofmaps[0].index_map, Vsub.dofmaps[0].index_map_bs) for Vsub in V[1]] # type: ignore[union-attr] + [(Vsub.dofmaps[0].index_map, Vsub.dofmaps[0].index_map_bs) for Vsub in V[1]] # type: ignore ) _bcs = [bc._cpp_object for bc in bcs] if bcs is not None else [] From 8055e0aa34e46b988b83eb2f0b4f97a8ac295bcb Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 18:53:32 +0200 Subject: [PATCH 11/19] Add more --- python/demo/demo_navier-stokes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/demo/demo_navier-stokes.py b/python/demo/demo_navier-stokes.py index 07e2a956ed..bef151d543 100644 --- a/python/demo/demo_navier-stokes.py +++ b/python/demo/demo_navier-stokes.py @@ -242,7 +242,7 @@ def f_expr(x): # We define some simulation parameters -n = 16 +n_el = 16 num_time_steps = 25 t_end = 10 Re = 25 # Reynolds Number @@ -254,7 +254,7 @@ def f_expr(x): # interpolate into for artifact free visualisation. # + -msh = mesh.create_unit_square(MPI.COMM_WORLD, n, n) +msh = mesh.create_unit_square(MPI.COMM_WORLD, n_el, n_el) # Function spaces for the velocity and for the pressure V = fem.functionspace(msh, ("Raviart-Thomas", k + 1)) From 31becb10608de22e0716ee4e6f7d9b1cc30fe9a0 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 18:56:39 +0200 Subject: [PATCH 12/19] change refs --- .github/workflows/fenicsx-refs.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fenicsx-refs.env b/.github/workflows/fenicsx-refs.env index 22c7e44a7e..7db9f61af8 100644 --- a/.github/workflows/fenicsx-refs.env +++ b/.github/workflows/fenicsx-refs.env @@ -1,5 +1,5 @@ basix_repository=FEniCS/basix -basix_ref=main +basix_ref=schnellerhase/mypy-dolfinx ufl_repository=FEniCS/ufl ufl_ref=main ffcx_repository=FEniCS/ffcx From b3be46a4eb5a28d82d5d088b972777e61a88592f Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 19:07:47 +0200 Subject: [PATCH 13/19] More fixes --- python/demo/demo_lagrange-variants.py | 2 +- python/demo/demo_navier-stokes.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/demo/demo_lagrange-variants.py b/python/demo/demo_lagrange-variants.py index 2f7687fa32..16199cc2b6 100644 --- a/python/demo/demo_lagrange-variants.py +++ b/python/demo/demo_lagrange-variants.py @@ -65,7 +65,7 @@ if MPI.COMM_WORLD.size == 1: for i in range(values.shape[1]): plt.plot(lattice, values[:, i]) - plt.plot(element._element.points, [0] * 11, "ko") + plt.plot(element.basix_element.points, [0] * 11, "ko") plt.ylim([-1, 6]) plt.savefig("demo_lagrange_variants_equispaced_10.png") plt.clf() diff --git a/python/demo/demo_navier-stokes.py b/python/demo/demo_navier-stokes.py index bef151d543..d2613bc0b3 100644 --- a/python/demo/demo_navier-stokes.py +++ b/python/demo/demo_navier-stokes.py @@ -413,7 +413,7 @@ def jump(phi, n): # We perform the time-stepping as a for-loop # + -for n in range(num_time_steps): +for _ in range(num_time_steps): t += delta_t.value navier_stokes_problem.solve() From 337b687c9f39e9ff757d906676996580556382c5 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 19:22:41 +0200 Subject: [PATCH 14/19] more --- python/demo/demo_lagrange-variants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/demo/demo_lagrange-variants.py b/python/demo/demo_lagrange-variants.py index 16199cc2b6..f77505cd2f 100644 --- a/python/demo/demo_lagrange-variants.py +++ b/python/demo/demo_lagrange-variants.py @@ -66,7 +66,7 @@ for i in range(values.shape[1]): plt.plot(lattice, values[:, i]) plt.plot(element.basix_element.points, [0] * 11, "ko") - plt.ylim([-1, 6]) + plt.ylim((-1, 6)) plt.savefig("demo_lagrange_variants_equispaced_10.png") plt.clf() # - From 4c8af56331fb53bf3a17e1a96ea7c24cd2814618 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 19:32:30 +0200 Subject: [PATCH 15/19] last --- python/demo/demo_lagrange-variants.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/demo/demo_lagrange-variants.py b/python/demo/demo_lagrange-variants.py index f77505cd2f..66ee67ab2b 100644 --- a/python/demo/demo_lagrange-variants.py +++ b/python/demo/demo_lagrange-variants.py @@ -98,7 +98,7 @@ for i in range(values.shape[1]): plt.plot(lattice, values[:, i]) plt.plot(element._element.points, [0] * 11, "ko") - plt.ylim([-1, 6]) + plt.ylim((-1, 6)) plt.savefig("demo_lagrange_variants_gll_10.png") plt.clf() # - @@ -152,7 +152,7 @@ def saw_tooth(x): plt.plot(pts, [saw_tooth(i[0]) for i in pts], "k--") plt.plot(pts, values, "r-") plt.legend(["function", "approximation"]) - plt.ylim([-0.1, 0.4]) + plt.ylim((-0.1, 0.4)) plt.title(variant.name) plt.savefig(f"demo_lagrange_variants_interpolation_{variant.name}.png") plt.clf() From 725c3b4546999c9807c5a270beb7d271a71a03c8 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 19:35:00 +0200 Subject: [PATCH 16/19] Revert --- .github/workflows/ccpp.yml | 10 +++++----- python/pyproject.toml | 4 ---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index f1e4bed74b..08cd0b7a73 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -2,11 +2,11 @@ name: CI on: push: - # branches: - # - main - # - release - # tags: - # - "v*" + branches: + - main + - release + tags: + - "v*" pull_request: branches: - main diff --git a/python/pyproject.toml b/python/pyproject.toml index 00952b728f..7fc752d557 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -103,10 +103,6 @@ warn_unused_ignores = false show_error_codes = true ignore_missing_imports = true -exclude = [ - # "demo/demo_lagrange-variants.py", - # "demo/demo_navier-stokes.py", -] [tool.ruff] line-length = 100 From 0da9f1c54e4d174799e1ddedf79873bc8017e851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20T=2E=20K=C3=BChner?= <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 19:37:08 +0200 Subject: [PATCH 17/19] Apply suggestion from @schnellerhase --- python/pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/python/pyproject.toml b/python/pyproject.toml index 7fc752d557..9a2aededc0 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -103,7 +103,6 @@ warn_unused_ignores = false show_error_codes = true ignore_missing_imports = true - [tool.ruff] line-length = 100 indent-width = 4 From 8c0f54b9ccb6dde44d874d224e5c9fe6f4b53e2f Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 20:08:56 +0200 Subject: [PATCH 18/19] one more --- python/dolfinx/io/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/dolfinx/io/utils.py b/python/dolfinx/io/utils.py index a6c4276d29..68838a11cd 100644 --- a/python/dolfinx/io/utils.py +++ b/python/dolfinx/io/utils.py @@ -213,6 +213,7 @@ def read_mesh( # Get coordinate element, special handling for second order # serendipity. + basix_el: basix.ufl._BasixElement | basix.ufl._BlockedElement num_nodes_per_cell = cells.shape[1] if (cell_shape == CellType.quadrilateral and num_nodes_per_cell == 8) or ( cell_shape == CellType.hexahedron and num_nodes_per_cell == 20 From cda8ec47e5648aa803643c676f8057527b14fbd7 Mon Sep 17 00:00:00 2001 From: schnellerhase <56360279+schnellerhase@users.noreply.github.com> Date: Thu, 9 Jul 2026 21:02:00 +0200 Subject: [PATCH 19/19] Use basix_element --- python/demo/demo_lagrange-variants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/demo/demo_lagrange-variants.py b/python/demo/demo_lagrange-variants.py index 66ee67ab2b..b615ef6fc7 100644 --- a/python/demo/demo_lagrange-variants.py +++ b/python/demo/demo_lagrange-variants.py @@ -97,7 +97,7 @@ if MPI.COMM_WORLD.size == 1: # Skip this plotting in parallel for i in range(values.shape[1]): plt.plot(lattice, values[:, i]) - plt.plot(element._element.points, [0] * 11, "ko") + plt.plot(element.basix_element.points, [0] * 11, "ko") plt.ylim((-1, 6)) plt.savefig("demo_lagrange_variants_gll_10.png") plt.clf()