Derivative of assembled stiffness matrix w.r.t coefficients

Let’s consider the nonlinear Poisson equation:

\begin{align*} -\mathrm{div}(q(x) \, \nabla u(x)) &= f(x), \quad & x &\in D = (0,1)^2\\ u(x) &= 0, \quad & x &\in \partial D \end{align*}

with the diffusion coefficient

q(x) = \overline{q}(x) + \sum_{j=1}^{n_q} r_j \cdot h_j(x),

where \overline{q}(x) and all h_j(x) are known. The well known weak formulation is

a(u, v) := \int_{D}q \, \nabla u \nabla v\, \mathrm{d}x = \int_{D} fv\, \mathrm{d}x =: L(v), \quad \forall v \in \hat{V}.

Is there any way to get the derivative of the assembled stiffness matrix A = (a(\phi_i, \phi_j))_{i,j} with respect to the coefficients r_1, \ldots, r_{n_q} without solving the PDE and the possibility to evaluate the derivative?


Here’s a minimal example:

  • q(x) = 1 + r_1 \sin{(\pi x_1)} + r_2 \sin{(2\pi x_2})
  • f(x) = x_1^2 - x_2^2

And what I tried so far:

from fenics import *

# create mesh and define function space
mesh = UnitSquareMesh(32, 32)
V = FunctionSpace(mesh, 'P', 1)     # P = Lagrange family, 1 = degree

# The diffusion coefficient and rhs of the PDE
r1 = Coefficient(V)
r2 = Coefficient(V)
q = Expression("1.0 + r1 * sin(pi*x[0]) + r2 * sin(pi*x[1])")
f = Expression('pow(x[0],2)-pow(x[1],2)', degree=2) #rhs of the PDE

# Homogenous Dirichlet boundary, i.e. u = 0 on the boundary
u_D = Constant(0.0)
bc = DirichletBC(V, u_D, lambda x: on_boundary: on_boundary)

# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)

# https://fenics.readthedocs.io/projects/ufl/en/latest/manual/form_language.html#variable-derivatives
w =  q * dot(grad(u), grad(v))
w = fd.variable(w)
F = w
dF = fd.diff(F, w)

# Bilinearform
a = dF * dx
# Linearform
L = f * v * dx

# Assemble System
A, b = assemble_system(a, L, bc)
# Not working :(

Unfortunately, I couldn’t find an example of this case. So any help is really appreciated!
Please let me know if you need further information.