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
24 changes: 8 additions & 16 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
- main
pull_request:

permissions:
contents: write

jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -27,22 +30,11 @@ jobs:
run: python -m pip install tox
- name: Build HTML documentation with tox
run: tox -e docs
- name: Commit changes to gh-pages branch
if: success() && github.event_name != 'pull_request'
run: |
git clone https://github.com/UCL/dxh.git --branch gh-pages --single-branch gh-pages
cp -r docs/_build/html/* gh-pages/
cd gh-pages
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .
git commit -m "Update documentation" -a || true
# The above command will fail if no changes were present, so we ignore
# the return code.
- name: Push changes to gh-pages branch
- name: Pubish documentation on GitHub pages
if: success() && github.event_name != 'pull_request'
uses: ad-m/github-push-action@v0.6.0
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: docs/_build/html
branch: gh-pages
directory: gh-pages
github_token: ${{ secrets.GITHUB_TOKEN }}
git-config-name: "github-actions[bot]"
git-config-email: "github-actions[bot]@users.noreply.github.com"
20 changes: 18 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,30 @@
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx.ext.napoleon"]
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.viewcode",
"sphinx.ext.napoleon",
"sphinx.ext.intersphinx",
"sphinx_autodoc_typehints",
]

templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]

napoleon_preprocess_types = True
python_use_unqualified_type_names = True

intersphinx_mapping = {
"python": ("https://docs.python.org/3/", None),
"numpy": ("https://numpy.org/doc/stable/", None),
"matplotlib": ("https://matplotlib.org/stable/", None),
"dolfinx": ("https://docs.fenicsproject.org/dolfinx/main/python", None),
"ufl": ("https://fenics.readthedocs.io/projects/ufl/en/stable/", None),
}

# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = "sphinx_rtd_theme"
html_theme = "pydata_sphinx_theme"
html_static_path = ["_static"]
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ optional-dependencies = {dev = [
"build",
"mypy",
"pre-commit",
"pydata-sphinx-theme",
"pytest",
"pytest-cov",
"ruff",
"sphinx<7",
"sphinx_rtd_theme",
"sphinx_autodoc_typehints",
"tox",
"twine",
]}
Expand Down Expand Up @@ -178,8 +179,9 @@ commands =
sphinx-apidoc -o docs src/ -T
sphinx-build -W -b html docs docs/_build/html
deps =
sphinx<7
sphinx_rtd_theme
sphinx
pydata-sphinx-theme
sphinx_autodoc_typehints

[tox]
envlist =
Expand Down
84 changes: 41 additions & 43 deletions src/dxh.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Helper functions for dolfinx."""
"""Helper functions for DOLFINx."""

from __future__ import annotations

Expand All @@ -19,12 +19,12 @@
if TYPE_CHECKING:
from dolfinx.mesh import Mesh
from matplotlib.colors import Colormap
from numpy.typing import ArrayLike, NDArray
from numpy.typing import NDArray


def get_matplotlib_triangulation_from_mesh(mesh: Mesh) -> Triangulation:
"""
Get matplotlib triangulation corresponding to dolfinx mesh.
Get Matplotlib triangulation corresponding to DOLFINx mesh.

Args:
mesh: Finite element mesh to get triangulation for.
Expand Down Expand Up @@ -80,7 +80,7 @@ def project_expression_on_function_space(
def evaluate_function_at_points(
function: Function,
points: NDArray[np.float64],
) -> ArrayLike:
) -> NDArray[np.float64]:
"""
Evaluate a finite element function at one or more points.

Expand Down Expand Up @@ -133,15 +133,12 @@ def _preprocess_functions(
return [(f.name, f) for f in functions]


OneDimensionalPlotArrangement = Literal["horizontal", "vertical", "stacked"]


def plot_1d_functions(
functions: Union[Function, Sequence[Function], dict[str, Function]],
*,
points: Optional[NDArray[np.float64]] = None,
axis_size: tuple[float, float] = (5.0, 5.0),
arrangement: OneDimensionalPlotArrangement = "horizontal",
arrangement: Literal["horizontal", "vertical", "stacked"] = "horizontal",
) -> plt.Figure:
"""
Plot one or more finite element functions on 1D domains using Matplotlib.
Expand All @@ -150,14 +147,16 @@ def plot_1d_functions(
functions: A single finite element function, sequence of functions or dictionary
mapping from string labels to finite element functions, in all cases
corresponding to the function(s) to plot. If a single function or sequence
of functions are specified the function `name` attribute(s) will be used to
set the title for each axis.
of functions are specified the function :py:attr:`name` attribute(s) will be
used to set the title for each axis.
points: Points to evaluate and plot function at. Defaults to nodes of mesh
function is defined on if :py:const:`None`.
axis_size: Size of axis to plot each function on in inches as `(width, height)`
tuple.
arrangment: One of "horizontal", "vertical" or "stacked" corresponding to
respectively plotting functions on separate axes in a single row, plotting
functions on separate axes in a single column or plotting functions all on a
single axis.
arrangement: One of :py:const:`"horizontal"`, :py:const:`"vertical"` or
:py:const:`"stacked"` corresponding to respectively plotting functions on
separate axes in a single row, plotting functions on separate axes in a
single column or plotting functions all on a single axis.

Returns:
Matplotlib figure object with plotted function(s).
Expand Down Expand Up @@ -195,19 +194,15 @@ def plot_1d_functions(
return fig


TwoDimensionalPlotType = Literal["pcolor", "surface"]
TwoDimensionalPlotArrangement = Literal["horizontal", "vertical"]


def plot_2d_functions(
functions: Union[Function, list[Function], dict[str, Function]],
*,
plot_type: TwoDimensionalPlotType = "pcolor",
plot_type: Literal["pcolor", "surface"] = "pcolor",
axis_size: tuple[float, float] = (5.0, 5.0),
colormap: Union[str, Colormap, None] = None,
show_colorbar: bool = True,
triangulation_color: Union[str, tuple[float, float, float], None] = None,
arrangement: TwoDimensionalPlotArrangement = "horizontal",
arrangement: Literal["horizontal", "vertical"] = "horizontal",
) -> plt.Figure:
"""
Plot one or more finite element functions on 2D domains using Matplotlib.
Expand All @@ -220,21 +215,23 @@ def plot_2d_functions(
functions: A single finite element function, sequence of functions or dictionary
mapping from string labels to finite element functions, in all cases
corresponding to the function(s) to plot. If a single function or sequence
of functions are specified the function `name` attribute(s) will be used to
set the title for each axis.
plot_type: String specifying type of plot to use for each function:
- "pcolor": pseudo color plot with function value represented by color,
- "surface": surface plot with function value represented by surface height.
of functions are specified the function :py:attr:`name` attribute(s) will be
used to set the title for each axis.
plot_type: String specifying type of plot to use for each function: Either
:py:const:`"pcolor"` for a pseudo color plot with function value represented
by color, or :py:const:`"surface"` for a surface plot with function value
represented by surface height.
axis_size: Size of axis to plot each function on in inches as `(width, height)`
tuple.
colormap: Matplotlib colormap to use to plot function values (if `None` default
colormap is used).
colormap: Matplotlib colormap to use to plot function values (if
:py:const:`None` default colormap is used).
show_colorbar: Whether to show a colorbar key showing color mapping for function
values.
triangulation_color: If not `None`, specifies the color (either as a string or
RGB tuple) to use to plot the mesh triangulation as an overlay on heatmap.
arrangement: Whether to arrange multiple axes vertically in a single
column rather than default of horizontally in a single row.
triangulation_color: If not :py:const:`None`, specifies the color (either as a
string or RGB tuple) to use to plot the mesh triangulation as an overlay on
heatmap.
arrangement: Whether to arrange multiple axes vertically in a single column
rather than default of horizontally in a single row.

Returns:
Matplotlib figure object with plotted function(s).
Expand Down Expand Up @@ -301,22 +298,23 @@ def define_dirichlet_boundary_condition(
] = None,
) -> DirichletBCMetaClass:
"""
Define dolfinx object representing Dirichlet boundary condition.
Define DOLFINx object representing Dirichlet boundary condition.

Args:
boundary_value: Fixed value(s) to enforce at domain boundary, either as a single
floating point (or `Constant`) value or a finite element function object
which gives the required values when evaluated at the boundary degrees of
freedom.
floating point (or :py:class:`dolfinx.fem.Constant`) value or a finite
element function object which gives the required values when evaluated at
the boundary degrees of freedom.
function_space: Argument specifying finite element function space from which
boundary degrees of freedom should be computed. If `boundary_values` is a
`Function` instance then should be set to `None` (the default) as in this
case `boundary_values.function_space` will be used as the relevant function
space.
boundary_indicator_function: If specified, a function evaluating to `True` when
the passed spatial coordinate is on the boundary and `False` otherwise. If
not specified (the default) then the boundary is assumed to correspond to
all exterior facets.
boundary degrees of freedom should be computed. If :py:obj:`boundary_values`
is a :py:class:`dolfinx.fem.Function` instance then should be set to
:py:const:`None` (the default) as in this case
:py:attr:`boundary_values.function_space` will be used as the relevant
function space.
boundary_indicator_function: If specified, a function evaluating to
:py:const:`True` when the passed spatial coordinate is on the boundary and
:py:const:`False` otherwise. If not specified (the default) then the
boundary is assumed to correspond to all exterior facets.

Returns:
Dirichlet boundary condition object.
Expand Down