Skip to content
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

Drop Python 3.9 support and add DOLFINx v0.8 support #22

Merged
merged 5 commits into from
Jul 23, 2024
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: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.9
python-version: 3.x
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cache: "pip"
cache-dependency-path: "pyproject.toml"
- name: Install tox
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
dolfinx-version: ["0.6", "0.7"]
python-version: ["3.10", "3.11", "3.12"]
dolfinx-version: ["0.6", "0.7", "0.8"]
exclude:
- dolfinx-version: "0.6"
python-version: "3.11"
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Centre for Advanced Research Computing, University College London

### Prerequisites

Compatible with Python 3.9 and 3.10.
Compatible with Python 3.10 and above.
[We recommend DOLFINx v0.7.0 or above to be installed](https://github.com/FEniCS/dolfinx#installation) although we support v0.6.0 for now.

### Installation
Expand Down Expand Up @@ -98,13 +98,13 @@ Tests can be run across all compatible Python versions in isolated environments
tox
```

from the root of the repository, or to run tests with Python 3.9 specifically run
from the root of the repository, or to run tests with Python 3.10 specifically run

```sh
tox -e test-py39
tox -e test-py310
```

substituting `py39` for `py310` to run tests with Python 3.10.
substituting `py310` for `py311` or `py312` to run tests with Python 3.11 or 3.12 respectively.

To run tests manually in a Python environment with `pytest` installed run

Expand Down
13 changes: 6 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ classifiers = [
"Operating System :: POSIX",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand Down Expand Up @@ -47,7 +46,7 @@ optional-dependencies = {dev = [
"twine",
]}
readme = "README.md"
requires-python = ">=3.9"
requires-python = ">=3.10"
license.file = "LICENCE.md"
urls.homepage = "https://github.com/UCL/dxh"

Expand Down Expand Up @@ -130,7 +129,7 @@ select = [
"W",
"YTT",
]
target-version = "py39"
target-version = "py310"
isort.known-first-party = [
"dxh",
]
Expand All @@ -157,7 +156,6 @@ overrides."tool.coverage.paths.source".inline_arrays = false
legacy_tox_ini = """
[gh-actions]
python =
3.9: py39
3.10: py310
3.11: py311
3.12: py312
Expand All @@ -166,11 +164,12 @@ python =
conda_deps =
dolfinx06: fenics-dolfinx==0.6.*
dolfinx07: fenics-dolfinx==0.7.*
dolfinx08: fenics-dolfinx==0.8.*
docs: fenics-dolfinx
conda_channels =
conda-forge

[testenv:test-py{39,311,310,312}-dolfinx{06,07}]
[testenv:test-py{310,311,312}-dolfinx{06,07,08}]
commands =
pytest --cov --cov-report=xml
deps =
Expand All @@ -188,8 +187,8 @@ deps =

[tox]
envlist =
test-py{39,310}-dolfinx{06,07}
test-py{311,312}-dolfinx07
test-py310-dolfinx{06,07,08}
test-py{311,312}-dolfinx{07,08}
docs
isolated_build = true
requires = tox-conda
Expand Down
79 changes: 45 additions & 34 deletions src/dxh.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
from typing import TYPE_CHECKING, Literal

if TYPE_CHECKING:
from collections.abc import Sequence
from typing import Callable, Optional, Union
from collections.abc import Callable, Sequence

Check warning on line 9 in src/dxh.py

View check run for this annotation

Codecov / codecov/patch

src/dxh.py#L9

Added line #L9 was not covered by tests

import dolfinx
import matplotlib.pyplot as plt
Expand All @@ -22,6 +21,13 @@
# Compatibility w [email protected]: try importing old DirichletBCMetaClass name.
from dolfinx.fem import DirichletBCMetaClass as DirichletBC

try:
from dolfinx.fem import functionspace
except ImportError:
# Compatibility w [email protected]: if the new functionspace function is not in DOLFINx
# then use the class constructor directly.
from dolfinx.fem import FunctionSpace as functionspace # noqa: N813

try:
from dolfinx.geometry import bb_tree, compute_collisions_points
except ImportError:
Expand Down Expand Up @@ -75,10 +81,9 @@


def project_expression_on_function_space(
expression: Union[
ufl.core.expr.Expr,
Callable[[ufl.SpatialCoordinate], ufl.core.expr.Expr],
],
expression: (
ufl.core.expr.Expr | Callable[[ufl.SpatialCoordinate], ufl.core.expr.Expr]
),
function_space: ufl.FunctionSpace,
) -> Function:
"""
Expand Down Expand Up @@ -154,7 +159,7 @@


def _preprocess_functions(
functions: Union[Function, Sequence[Function], dict[str, Function]],
functions: Function | Sequence[Function] | dict[str, Function],
) -> list[tuple[str, Function]]:
if isinstance(functions, Function):
return [(functions.name, functions)]
Expand All @@ -165,9 +170,9 @@


def plot_1d_functions(
functions: Union[Function, Sequence[Function], dict[str, Function]],
functions: Function | Sequence[Function] | dict[str, Function],
*,
points: Optional[NDArray[np.float64]] = None,
points: NDArray[np.float64] | None = None,
axis_size: tuple[float, float] = (5.0, 5.0),
arrangement: Literal["horizontal", "vertical", "stacked"] = "horizontal",
) -> plt.Figure:
Expand Down Expand Up @@ -226,13 +231,13 @@


def plot_2d_functions(
functions: Union[Function, list[Function], dict[str, Function]],
functions: Function | list[Function] | dict[str, Function],
*,
plot_type: Literal["pcolor", "surface"] = "pcolor",
axis_size: tuple[float, float] = (5.0, 5.0),
colormap: Union[str, Colormap, None] = None,
colormap: str | Colormap | None = None,
show_colorbar: bool = True,
triangulation_color: Union[str, tuple[float, float, float], None] = None,
triangulation_color: str | tuple[float, float, float] | None = None,
arrangement: Literal["horizontal", "vertical"] = "horizontal",
) -> plt.Figure:
"""
Expand Down Expand Up @@ -281,7 +286,11 @@
raise ValueError(msg)
subplot_kw = {"projection": "3d"} if plot_type == "surface" else {}
fig, axes = plt.subplots(n_rows, n_cols, figsize=figsize, subplot_kw=subplot_kw)
for ax, (label, function) in zip(np.atleast_1d(axes), label_and_functions):
for ax, (label, function) in zip(
np.atleast_1d(axes),
label_and_functions,
strict=True,
):
mesh = function.function_space.mesh
if mesh.topology.dim != 2:
msg = "Only two-dimensional spatial domains are supported"
Expand Down Expand Up @@ -321,12 +330,10 @@


def define_dirichlet_boundary_condition(
boundary_value: Union[Function, Constant, float],
function_space: Optional[FunctionSpace] = None,
boundary_value: Function | Constant | float,
function_space: FunctionSpace | None = None,
*,
boundary_indicator_function: Optional[
Callable[[ufl.SpatialCoordinate], bool]
] = None,
boundary_indicator_function: Callable[[ufl.SpatialCoordinate], bool] | None = None,
) -> DirichletBC:
"""
Define DOLFINx object representing Dirichlet boundary condition.
Expand Down Expand Up @@ -359,20 +366,21 @@
msg = "function_space must not be None if boundary_value is not a Function"
raise ValueError(msg)
mesh = function_space.mesh
facet_dim = mesh.topology.dim - 1
if boundary_indicator_function is not None:
boundary_dofs = dolfinx.fem.locate_dofs_geometrical(
function_space,
boundary_facets = dolfinx.mesh.locate_entities_boundary(
mesh,
facet_dim,
boundary_indicator_function,
)
else:
facet_dim = mesh.topology.dim - 1
mesh.topology.create_connectivity(facet_dim, mesh.topology.dim)
boundary_facets = dolfinx.mesh.exterior_facet_indices(mesh.topology)
boundary_dofs = dolfinx.fem.locate_dofs_topological(
function_space,
facet_dim,
boundary_facets,
)
boundary_dofs = dolfinx.fem.locate_dofs_topological(
function_space,
facet_dim,
boundary_facets,
)
return dolfinx.fem.dirichletbc(
boundary_value,
boundary_dofs,
Expand All @@ -382,11 +390,11 @@

def error_norm(
function_1: dolfinx.fem.Function,
function_or_expression_2: Union[
dolfinx.fem.Function,
ufl.core.expr.Expr,
Callable[[ufl.SpatialCoordinate], ufl.core.expr.Expr],
],
function_or_expression_2: (
dolfinx.fem.Function
| ufl.core.expr.Expr
| Callable[[ufl.SpatialCoordinate], ufl.core.expr.Expr]
),
degree_raise: int = 3,
norm_order: Literal[1, 2, "inf-dof"] = 2,
) -> float:
Expand Down Expand Up @@ -440,10 +448,13 @@
Computed Lᵖ error norm value.
"""
# Create raised degree function space with same element as for original function_1
original_degree = function_1.function_space.ufl_element().degree()
family = function_1.function_space.ufl_element().family()
original_degree = function_1.function_space.ufl_element().degree
if callable(original_degree):
# Depending on Basix version degree may be an accesor method or attribute
original_degree = original_degree()
family = function_1.function_space.ufl_element().family_name
mesh = function_1.function_space.mesh
raised_degree_function_space = FunctionSpace(
raised_degree_function_space = functionspace(
mesh,
(family, original_degree + degree_raise),
)
Expand Down
Loading
Loading