Use of `ufl.derivative` for `MixedFunctionSpace`

I try to use ufl.derivative for a mixed case with the following script (I did not add the boundary conditions to reduce the size of the example):

import dolfinx
import basix
import ufl

from mpi4py import MPI

msh = dolfinx.mesh.create_rectangle(comm=MPI.COMM_WORLD, points=((0.0, 0.0), (2.0, 1.0)), n=(5, 1), cell_type=dolfinx.mesh.CellType.triangle)
gdim = msh.geometry.dim

poly_o = 1
vector_element = basix.ufl.element("DG", msh.topology.cell_name(), poly_o+1, shape=(gdim,))
scalar_element = basix.ufl.element("DG", msh.topology.cell_name(), poly_o)

V = dolfinx.fem.functionspace(msh, vector_element)
Q = dolfinx.fem.functionspace(msh, scalar_element)
VQ = ufl.MixedFunctionSpace(V, Q)

u, p = dolfinx.fem.Function(V), dolfinx.fem.Function(Q)
(v, q) = ufl.TestFunctions(VQ)

a = - ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
a += - ufl.inner(p, ufl.div(v)) * ufl.dx
a += - ufl.inner(u, ufl.grad(q)) * ufl.dx

a_blocked = ufl.extract_blocks(a)
F = dolfinx.fem.form(a_blocked)

j = ufl.derivative(a, (u, p), (v, q))
j_blocked = ufl.extract_blocks(j)
J = dolfinx.fem.form(j_blocked)

The last lines returns the error:

ufl.algorithms.check_arities.ArityMismatch: Multiplying expressions with overlapping form argument number 0, argument is v_0^0.

Could you, please, help me here?

I cannot comment on the problem with ufl.derivative but if you are willing to do the book keeping manually, here is a working example on how to construct a block Newton solver.

This is because you are re-using the test-functions, rather than differentiating in the direction of the TrialFunctions, i.e.

import dolfinx
import basix
import ufl

from mpi4py import MPI

msh = dolfinx.mesh.create_rectangle(
    comm=MPI.COMM_WORLD,
    points=((0.0, 0.0), (2.0, 1.0)),
    n=(5, 1),
    cell_type=dolfinx.mesh.CellType.triangle,
)
gdim = msh.geometry.dim

poly_o = 1
vector_element = basix.ufl.element(
    "DG", msh.topology.cell_name(), poly_o + 1, shape=(gdim,)
)
scalar_element = basix.ufl.element("DG", msh.topology.cell_name(), poly_o)

V = dolfinx.fem.functionspace(msh, vector_element)
Q = dolfinx.fem.functionspace(msh, scalar_element)
VQ = ufl.MixedFunctionSpace(V, Q)

u, p = dolfinx.fem.Function(V), dolfinx.fem.Function(Q)
(v, q) = ufl.TestFunctions(VQ)

a = -ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
a += -ufl.inner(p, ufl.div(v)) * ufl.dx
a += -ufl.inner(u, ufl.grad(q)) * ufl.dx

a_blocked = ufl.extract_blocks(a)
F = dolfinx.fem.form(a_blocked)

j = ufl.derivative(a, (u, p), ufl.TrialFunctions(VQ))
j_blocked = ufl.extract_blocks(j)
J = dolfinx.fem.form(j_blocked)
1 Like