Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
c7426b2
simplify
leo-collins Sep 23, 2025
106ea87
tidy function interpolate
leo-collins Sep 23, 2025
91caf94
create Coargument in Firedrake
leo-collins Sep 23, 2025
91e4500
Change `Interpolate` to `interpolate`
leo-collins Sep 23, 2025
f661be2
update `test_interp_dual.py`
leo-collins Sep 23, 2025
bc4e48b
DROP BEFORE MERGE: use UFL branch
leo-collins Sep 23, 2025
ac252dc
move FunctionSpace check into `Interpolate`
leo-collins Sep 23, 2025
79d6c83
lint
leo-collins Sep 23, 2025
4a509f7
test -> trial
leo-collins Sep 24, 2025
812f5d8
tidy function.interpolate
leo-collins Oct 1, 2025
e50cf4e
tidy cofunction.interpolate
leo-collins Oct 1, 2025
5d9c81e
tidy type hints in function.py
leo-collins Oct 1, 2025
fddcb79
remove UFL branch
leo-collins Oct 1, 2025
1bc83d4
lint
leo-collins Oct 1, 2025
8ce32ae
fix typing
leo-collins Oct 1, 2025
78dac92
runtimeerror -> valueerror
leo-collins Oct 1, 2025
62aff37
add check for shape mismatch to `Interpolate`
leo-collins Oct 1, 2025
68e5527
use ufl.as_expr
leo-collins Oct 2, 2025
d782365
update expr arg check
leo-collins Oct 6, 2025
f6f4a11
lint
leo-collins Oct 6, 2025
3a59ff1
fix check
leo-collins Oct 6, 2025
5b57198
Merge branch 'leo/simplify-interpolate' into leo/refactor_interpolate
leo-collins Oct 16, 2025
c8ffb2b
tidy
leo-collins Oct 1, 2025
8ffb3fc
review suggestions
leo-collins Oct 1, 2025
a73e23f
Squashed commit of the following:
leo-collins Oct 1, 2025
37b9cac
tidy
leo-collins Oct 1, 2025
90a0fa5
remove `V` argument
leo-collins Oct 8, 2025
72bd29e
assemble cross-mesh interpolation matrix; add test
leo-collins Oct 8, 2025
a8e7d30
assemble adjoint cross-mesh interpolation matrix
leo-collins Oct 8, 2025
40c23da
changes
leo-collins Oct 9, 2025
fcdb7c5
remove repeated checks
leo-collins Oct 9, 2025
e7fe358
progress on adjoint cross-mesh / vom-to-vom
leo-collins Oct 9, 2025
efc45c7
tidy
leo-collins Oct 9, 2025
f71dd47
tidy
leo-collins Oct 9, 2025
17469c5
fixes
leo-collins Oct 10, 2025
21d1068
fixes
leo-collins Oct 10, 2025
19187a5
fixed zero-form cross mesh
leo-collins Oct 10, 2025
d17d049
remove vomontovomwrapper
leo-collins Oct 10, 2025
4c4cf49
fixes
leo-collins Oct 11, 2025
58326de
tidy import
leo-collins Oct 11, 2025
a78b652
lint
leo-collins Oct 11, 2025
387ad5e
attempt fix for bc
leo-collins Oct 13, 2025
7f1d509
fix
leo-collins Oct 13, 2025
78b058a
make `_get_interpolator` public
leo-collins Oct 13, 2025
c9f4ac0
change bcs
leo-collins Oct 13, 2025
2340cea
fixes
leo-collins Oct 13, 2025
7979355
updates
leo-collins Oct 14, 2025
b3ce8f3
remove _interpolate WIP
leo-collins Oct 14, 2025
ca93fbd
fixes
leo-collins Oct 14, 2025
39aef14
add `get_interpolator` to `__all__`
leo-collins Oct 14, 2025
3658338
lint; type hints and docstrings
leo-collins Oct 14, 2025
b9ab2e0
fix
leo-collins Oct 14, 2025
93476e4
suggestions
leo-collins Oct 16, 2025
0934e61
fixes
leo-collins Oct 16, 2025
6b87a6b
lint
leo-collins Oct 16, 2025
15bdd53
pass bcs to `interpolate`, zero cofunction fix
leo-collins Oct 16, 2025
d54994e
Interpolate: map dual argument to reference values for codegen
pbrubeck Oct 16, 2025
8667567
add zero form optimisation back in
leo-collins Oct 16, 2025
59bcb4d
conjugate test function
leo-collins Oct 16, 2025
86ea049
fixes
leo-collins Oct 17, 2025
0e2e107
suggestions / tidy
leo-collins Oct 18, 2025
7694538
fixes docs
leo-collins Oct 20, 2025
0cfc6e9
lint
leo-collins Oct 21, 2025
cece271
Merge branch 'leo/refactor_interpolate' into pbrubeck/fix/interp-refe…
pbrubeck Oct 22, 2025
2e7df2f
Fix TSFC tests
pbrubeck Oct 22, 2025
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
23 changes: 10 additions & 13 deletions .github/workflows/core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ on:
description: Whether to run the test suite
type: boolean
default: true
build_docs:
description: Whether to build the documentation
type: boolean
default: true
test_macos:
description: Whether to test using macOS
type: boolean
Expand Down Expand Up @@ -42,6 +46,10 @@ on:
description: Whether to run the test suite
type: boolean
default: true
build_docs:
description: Whether to build the documentation
type: boolean
default: true
test_macos:
description: Whether to test using macOS
type: boolean
Expand Down Expand Up @@ -82,7 +90,6 @@ jobs:
OMP_NUM_THREADS: 1
OPENBLAS_NUM_THREADS: 1
FIREDRAKE_CI: 1
PYOP2_CI_TESTS: 1
PYOP2_SPMD_STRICT: 1
# NOTE: One should occasionally update test_durations.json by running
# 'make test_durations' inside a 'firedrake:latest' Docker image.
Expand Down Expand Up @@ -134,17 +141,6 @@ jobs:
exit 1
fi

# Raise an error if any 'TODO RELEASE' comments remain
- name: Check no 'TODO RELEASE' comments (release only)
if: inputs.target_branch == 'release'
working-directory: firedrake-repo
run: |
if [ -z "$( grep -r --exclude-dir='.*' 'TODO RELEASE' )" ]; then
exit 0
else
exit 1
fi

- name: Install system dependencies (2)
run: |
apt-get -y install \
Expand Down Expand Up @@ -207,7 +203,7 @@ jobs:

: # Install from an sdist so we can make sure that it is not ill-formed
pip install build
python -m build ./firedrake-repo --sdist "$EXTRA_BUILD_ARGS"
python -m build ./firedrake-repo --sdist $EXTRA_BUILD_ARGS

pip install --verbose $EXTRA_PIP_FLAGS \
--no-binary h5py \
Expand Down Expand Up @@ -488,6 +484,7 @@ jobs:
run: make lint GITHUB_ACTIONS_FORMATTING=1

build_docs:
if: inputs.build_docs
name: Build documentation
runs-on: [self-hosted, Linux]
container:
Expand Down
17 changes: 5 additions & 12 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,11 @@ jobs:
matrix:
os: [Linux, macOS]
arch: [default, complex]
platform: [linux/amd64, linux/arm64]
# Cannot use inputs in exclude clauses, so add a dummy matrix dim
build_dev:
- ${{ inputs.build_dev }}
# exclude incompatible os+platform, and only build linux dev containers
exclude:
- os: Linux
platform: linux/arm64
- os: macOS
platform: linux/amd64
- os: macOS
build_dev: true
include:
- os: Linux
platform: linux/amd64
- os: macOS
platform: linux/arm64
uses: ./.github/workflows/docker_build.yml
with:
os: ${{ matrix.os }}
Expand Down
64 changes: 57 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,74 @@
name: Publish release

on:
release:
types: [released]
workflow_dispatch:
inputs:
branch:
description: The branch to release from
type: string
required: true
version:
description: The version number to release
type: string
required: true

jobs:
deploy:
check:
name: Pre-release checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
path: firedrake-repo
ref: ${{ inputs.branch }}

- name: Check no 'TODO RELEASE' comments remain
working-directory: firedrake-repo
run: |
if [ -z "$( grep -r --exclude-dir='.*' 'TODO RELEASE' )" ]; then
exit 0
else
exit 1
fi

- name: Check version number matches
working-directory: firedrake-repo
run: |
if [ -z "$( grep 'version = \"${{ inputs.version }}\"' pyproject.toml )" ]; then
exit 1
else
exit 0
fi

pypi:
uses: ./.github/workflows/core.yml
needs: check
with:
source_ref: release
source_ref: ${{ inputs.branch }}
target_branch: release
run_tests: false
build_docs: false
upload_pypi: true
secrets: inherit

github_release:
name: Create GitHub release
needs: pypi
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v5
- name: Create release
env:
GH_TOKEN: ${{ github.token }}
run: gh release create --title ${{ inputs.version }} --target ${{ inputs.branch }} --generate-notes ${{ inputs.version }}

docker:
name: Build Docker containers
uses: ./.github/workflows/docker.yml
needs: pypi
with:
tag: ${{ github.ref_name }}
branch: ${{ github.ref_name }}
build_dev: false
tag: ${{ inputs.version }}
branch: ${{ inputs.branch }}
secrets: inherit
2 changes: 1 addition & 1 deletion demos/boussinesq/boussinesq.py.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ implements a boundary condition that fixes a field at a single point. ::

# Take the basis function with the largest abs value at bc_point
v = TestFunction(V)
F = assemble(Interpolate(inner(v, v), Fvom))
F = assemble(interpolate(inner(v, v), Fvom))
with F.dat.vec as Fvec:
max_index, _ = Fvec.max()
nodes = V.dof_dset.lgmap.applyInverse([max_index])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ for 3 wave sources. Therefore, we will have 3 emsemble members, each with 2 rank
processes launched by mpiexec must therefore be equal to the product of number of ensemble members
(3, in this case) with the number of processes to be used for each ensemble member (``M=2``, in this case).
Additional details about the ensemble parallelism can be found in the
`Firedrake documentation <https://www.firedrakeproject.org/parallelism.html#ensemble-parallelism>`_.
`Firedrake documentation <https://www.firedrakeproject.org/ensemble_parallelism.html>`_.

The subcommunicators in each ensemble member are: ``Ensemble.comm`` and ``Ensemble.ensemble_comm``.
``Ensemble.comm`` is the spatial communicator. ``Ensemble.ensemble_comm`` allows communication between
Expand Down
2 changes: 1 addition & 1 deletion demos/multicomponent/multicomponent.py.rst
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ mathematically valid to do this)::

# Take the basis function with the largest abs value at bc_point
v = TestFunction(V)
F = assemble(Interpolate(inner(v, v), Fvom))
F = assemble(interpolate(inner(v, v), Fvom))
with F.dat.vec as Fvec:
max_index, _ = Fvec.max()
nodes = V.dof_dset.lgmap.applyInverse([max_index])
Expand Down
12 changes: 6 additions & 6 deletions demos/saddle_point_pc/saddle_point_systems.py.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ Finally, at each mesh size, we print out the number of cells in the
mesh and the number of iterations the solver took to converge ::

#
print(w.function_space().mesh().num_cells(), solver.snes.ksp.getIterationNumber())
print(w.function_space().mesh().unique().num_cells(), solver.snes.ksp.getIterationNumber())

The resulting convergence is unimpressive:

Expand Down Expand Up @@ -282,7 +282,7 @@ applying the action of blocks, so we can use a block matrix format. ::
for n in range(8):
solver, w = build_problem(n, parameters, block_matrix=True)
solver.solve()
print(w.function_space().mesh().num_cells(), solver.snes.ksp.getIterationNumber())
print(w.function_space().mesh().unique().num_cells(), solver.snes.ksp.getIterationNumber())

The resulting convergence is algorithmically good, however, the larger
problems still take a long time.
Expand Down Expand Up @@ -367,7 +367,7 @@ Let's see what happens. ::
for n in range(8):
solver, w = build_problem(n, parameters, block_matrix=True)
solver.solve()
print(w.function_space().mesh().num_cells(), solver.snes.ksp.getIterationNumber())
print(w.function_space().mesh().unique().num_cells(), solver.snes.ksp.getIterationNumber())

This is much better, the problem takes much less time to solve and
when observing the iteration counts for inverting :math:`S` we can see
Expand Down Expand Up @@ -422,7 +422,7 @@ and so we no longer need a flexible Krylov method. ::
for n in range(8):
solver, w = build_problem(n, parameters, block_matrix=True)
solver.solve()
print(w.function_space().mesh().num_cells(), solver.snes.ksp.getIterationNumber())
print(w.function_space().mesh().unique().num_cells(), solver.snes.ksp.getIterationNumber())

This results in the following GMRES iteration counts

Expand Down Expand Up @@ -487,7 +487,7 @@ variable. We can provide it as an :class:`~.AuxiliaryOperatorPC` via a python pr
for n in range(8):
solver, w = build_problem(n, parameters, aP=None, block_matrix=False)
solver.solve()
print(w.function_space().mesh().num_cells(), solver.snes.ksp.getIterationNumber())
print(w.function_space().mesh().unique().num_cells(), solver.snes.ksp.getIterationNumber())

This actually results in slightly worse convergence than the diagonal
approximation we used above.
Expand Down Expand Up @@ -571,7 +571,7 @@ Let's see what the iteration count looks like now. ::
for n in range(8):
solver, w = build_problem(n, parameters, aP=riesz, block_matrix=True)
solver.solve()
print(w.function_space().mesh().num_cells(), solver.snes.ksp.getIterationNumber())
print(w.function_space().mesh().unique().num_cells(), solver.snes.ksp.getIterationNumber())

============== ==================
Mesh elements GMRES iterations
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile.vanilla
Original file line number Diff line number Diff line change
Expand Up @@ -168,5 +168,5 @@ ENV PYOP2_CFLAGS=$CFLAGS

# Run the smoke tests.
RUN cd /opt/firedrake/ \
&& firedrake-check \
&& firedrake-check --mpiexec 'mpiexec --oversubscribe -n' \
&& firedrake-clean
6 changes: 3 additions & 3 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@
r'https://www.hilton.com/en/hotels/leehnhn-hilton-leeds-city/',
r'https://www.radissonhotels.com/en-us/hotels/park-plaza-leeds',
r'https://www.radissonhotels.com/en-us/hotels/radisson-blu-leeds'
r'https://www.radissonhotels.com/en-us/hotels/radisson-blu-leeds',
r'https://all.accor.com/hotel/*',
]
linkcheck_timeout = 30

Expand Down Expand Up @@ -413,10 +415,8 @@

intersphinx_mapping = {
'pyop2': ('https://op2.github.io/PyOP2', None),
'ufl': ('https://fenics.readthedocs.io/projects/ufl/en/latest/', None),
'ufl': ('https://docs.fenicsproject.org/ufl/main/', None),
'FIAT': ('https://fenics.readthedocs.io/projects/fiat/en/latest/', None),
'FInAT': ('https://finat.github.io/FInAT/', None),
'FIAT': ('https://firedrakeproject.org/fiat', None),
'petsctools': ('https://firedrakeproject.org/petsctools/', None),
'mpi4py': ('https://mpi4py.readthedocs.io/en/stable/', None),
'h5py': ('http://docs.h5py.org/en/latest/', None),
Expand Down
16 changes: 13 additions & 3 deletions docs/source/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,19 @@ firedrake-configure
-------------------

To simplify the installation process, Firedrake provides a utility script called
``firedrake-configure``. This script can be downloaded by executing::
``firedrake-configure``. This script can be downloaded by executing:

$ curl -O https://raw.githubusercontent.com/firedrakeproject/firedrake/main/scripts/firedrake-configure
.. only:: release

.. code-block:: text

$ curl -O https://raw.githubusercontent.com/firedrakeproject/firedrake/release/scripts/firedrake-configure

.. only:: main

.. code-block:: text

$ curl -O https://raw.githubusercontent.com/firedrakeproject/firedrake/main/scripts/firedrake-configure

Note that ``firedrake-configure`` **does not install Firedrake for you**. It
is simply a helper script that emits the configuration options that Firedrake
Expand Down Expand Up @@ -580,7 +590,7 @@ should be followed:

#. Install Firedrake in editable mode without build isolation::

$ pip install --no-build-isolation --no-binary h5py --editable './firedrake[check]'
$ pip install --no-build-isolation --no-binary h5py --editable './firedrake[check,docs]'


Editing subpackages
Expand Down
2 changes: 1 addition & 1 deletion firedrake/adjoint/ensemble_reduced_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class EnsembleReducedFunctional(AbstractReducedFunctional):
The functionals :math:`J_i` and the control must be defined over a common
`ensemble.comm` communicator. To understand more about how ensemble parallelism
works, please refer to the `Firedrake manual
<https://www.firedrakeproject.org/parallelism.html#ensemble-parallelism>`_.
<https://www.firedrakeproject.org/ensemble_parallelism.html>`_.
"""
def __init__(self, functional, control, ensemble, scatter_control=True,
gather_functional=None,
Expand Down
13 changes: 10 additions & 3 deletions firedrake/adjoint_utils/blocks/solving.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ def _should_compute_boundary_adjoint(self, relevant_dependencies):
def adj_sol(self):
return self.adj_state

@adj_sol.setter
def adj_sol(self, value):
if self.adj_state is None:
self.adj_state = value.copy(deepcopy=True)
else:
self.adj_state.assign(value)

def prepare_evaluate_adj(self, inputs, adj_inputs, relevant_dependencies):
fwd_block_variable = self.get_outputs()[0]
u = fwd_block_variable.output
Expand All @@ -187,7 +194,7 @@ def prepare_evaluate_adj(self, inputs, adj_inputs, relevant_dependencies):
adj_sol, adj_sol_bdy = self._assemble_and_solve_adj_eq(
dFdu_form, dJdu, compute_bdy
)
self.adj_state = adj_sol
self.adj_sol = adj_sol
if self.adj_cb is not None:
self.adj_cb(adj_sol)
if self.adj_bdy_cb is not None and compute_bdy:
Expand Down Expand Up @@ -408,7 +415,7 @@ def prepare_evaluate_hessian(self, inputs, hessian_inputs, adj_inputs,
firedrake.derivative(dFdu_form, fwd_block_variable.saved_output,
tlm_output))

adj_sol = self.adj_state
adj_sol = self.adj_sol
if adj_sol is None:
raise RuntimeError("Hessian computation was run before adjoint.")
bdy = self._should_compute_boundary_adjoint(relevant_dependencies)
Expand Down Expand Up @@ -726,7 +733,7 @@ def prepare_evaluate_adj(self, inputs, adj_inputs, relevant_dependencies):
relevant_dependencies
)
adj_sol, adj_sol_bdy = self._adjoint_solve(adj_inputs[0], compute_bdy)
self.adj_state = adj_sol
self.adj_sol = adj_sol
if self.adj_cb is not None:
self.adj_cb(adj_sol)
if self.adj_bdy_cb is not None and compute_bdy:
Expand Down
2 changes: 1 addition & 1 deletion firedrake/adjoint_utils/variational_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def wrapper(self, *args, **kwargs):
# Try again without expanding derivatives,
# as dFdu might have been simplied to an empty Form
self._ad_adj_F = adjoint(dFdu, derivatives_expanded=True)
except (TypeError, NotImplementedError):
except (ValueError, TypeError, NotImplementedError):
self._ad_adj_F = None
self._ad_kwargs = {'Jp': self.Jp, 'form_compiler_parameters': self.form_compiler_parameters, 'is_linear': self.is_linear}
self._ad_count_map = {}
Expand Down
Loading
Loading