Multiplication of integrals is unsupported

Dear community,

I would like to solve a variational problem with terms of the form:

\left(\int_{\Gamma}uds\right)\left(\int_{\Gamma}vds\right)

where \Gamma is a part of the boundary, u and v are real valued functions.
It is a multiplication of two integrals.

My DOLFINx version is 0.9.0. It was installed from conda-forge. I am working in a computer with ubuntu 22.04.

Below a “minimum working code example” to illustrate the problem:

import ufl
import numpy as np
from mpi4py import MPI
import dolfinx
from dolfinx import mesh
from dolfinx.fem import functionspace
from dolfinx.fem.petsc import LinearProblem

print(f"DOLFINx version: {dolfinx.__version__}")

domain = mesh.create_unit_square(MPI.COMM_WORLD, 8, 8, mesh.CellType.quadrilateral)

def left(x):
    return np.isclose(x[0], 0.)

def right(x):
    return np.isclose(x[0], 1.)


fdim = domain.topology.dim - 1
left_facets = mesh.locate_entities_boundary(domain, fdim, left)
right_facets = mesh.locate_entities_boundary(domain, fdim, right)

marked_facets = np.hstack([left_facets, right_facets])
marked_values = np.hstack([np.full_like(left_facets, 1), np.full_like(right_facets, 2)])
sorted_facets = np.argsort(marked_facets)
facet_tag = mesh.meshtags(domain, fdim, marked_facets[sorted_facets], marked_values[sorted_facets])
ds = ufl.Measure('ds', domain=domain, subdomain_data=facet_tag)

V = functionspace(domain, ("Lagrange", 1))
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)
a = ufl.dot(ufl.grad(u), ufl.grad(v)) * ufl.dx + \
    (u*v*ds(1) - (u*ds(1))*(v*ds(1))) + (u*v*ds(2) - (u*ds(2))*(v*ds(2)))
L = v*ds(1) - v*ds(2)

problem = LinearProblem(a, L)
uh = problem.solve()

The full error message is the following:

DOLFINx version: 0.9.0
Traceback (most recent call last):
  File "/home/josue/Documents/MisTrabajos/Regularization_all-at-once_EIT/test.py", line 34, in <module>
    (u*v*ds(1) - (u*ds(1))*(v*ds(1))) + (u*v*ds(2) - (u*ds(2))*(v*ds(2)))
                 ~~~~~~~~~^^~~~~~~~~
TypeError: unsupported operand type(s) for *: 'Form' and 'Form'

I guess that this multiplication is not supported.

Do you know another way to write these kinds of terms?

Assemble each of them as matrices and then in turn do sparse matrix matrix multiplication.

Hello dokken,

Thanks for your help. I wrote

ufl.dot(ufl.as_matrix([[u*ds(1)]]),ufl.as_matrix([[v*ds(1)]]))

instead of

(u*ds(1))*(v*ds(1))

but it does not work. Could you provide more details about Assemble each of them as matrices?

This is an incredibly dense matrix. Are you sure you want this in your variational form?

I would compute
a=dolfinx.fem.petsc.assemble_vector(dolfinx.fem.form(u*ds(1)))
b=dolfinx.fem.petsc.assemble_vector(dolfinx.fem.form(v*ds(1)))

Then find the nonzero entries of these two vectors, (hopefully there are many).

One can then in turn add these to an assembled matrix A with setvalueslocal as for instance shown in: