Quadrature elements and boundary integration

Hello everyone,
I am currently facing difficulties with the use of quadrature elements. I have an internal variable (damage) that I would like to only define at the integration points. I am performing explicit dynamic simulations and need to form the residual Res = a(u, u_) - l(u_). My issue lies in the definition of the right-hand side, especially when there are loads on a boundary of the domain. Indeed, I encounter an error message when trying to construct form(Res) with a surface measure ds. I have provided a MWE below illustrating the problem:

from dolfinx.fem import Function, FunctionSpace, form
from dolfinx.mesh import create_unit_interval
from ufl import Measure, TestFunction, FiniteElement, inner
from mpi4py.MPI import COMM_WORLD

mesh = create_unit_interval(COMM_WORLD, 1)
V = FunctionSpace(mesh, ("CG", 1))

working = False
if working:
    V_d  = FunctionSpace(mesh, ("DG", 0))
if not working:
    W0e = FiniteElement("Quadrature", mesh.ufl_cell(), degree = 1, quad_scheme="default")
    V_d  = FunctionSpace(mesh, W0e)
lmbda = 2
mu = 3

def eps_xx(v):
    return v.dx(0)

def sigma_xx(v, d):
    return (1-d)**2 * (lmbda * v.dx(0) + 2 * mu * v.dx(0))

u = Function(V, name = "displacement")
u_ = TestFunction(V)
d = Function(V_d, name = "damage")
metadata = {"quadrature_rule": "default", "quadrature_degree": 1}
dx = Measure("dx", domain = mesh, metadata = metadata)
ds = Measure('ds')
a = inner(sigma_xx(u, d), eps_xx(u_)) * dx
l = 1 * u_ * ds
residual = a - l
residual_form = form(residual)

I suspect that this has to do with the position of the integration points.
EDIT: Here is the error:

  File "/home/bouteillerp/.local/lib/python3.10/site-packages/spyder_kernels/py3compat.py", line 356, in compat_exec
    exec(code, globals, locals)

  File "/home/bouteillerp/Bureau/Codes/Dolfinx/Debug_Fenicsx/Melange_quadrature.py", line 33, in <module>
    residual_form = form(residual)

  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/fem/forms.py", line 188, in form
    return _create_form(form)

  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/fem/forms.py", line 183, in _create_form
    return _form(form)

  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/fem/forms.py", line 141, in _form
    ufcx_form, module, code = jit.ffcx_jit(mesh.comm, form,

  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/jit.py", line 56, in mpi_jit
    return local_jit(*args, **kwargs)

  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/jit.py", line 204, in ffcx_jit
    r = ffcx.codegeneration.jit.compile_forms([ufl_object], options=p_ffcx, **p_jit)

  File "/usr/lib/python3/dist-packages/ffcx/codegeneration/jit.py", line 199, in compile_forms
    raise e

  File "/usr/lib/python3/dist-packages/ffcx/codegeneration/jit.py", line 190, in compile_forms
    impl = _compile_objects(decl, forms, form_names, module_name, p, cache_dir,

  File "/usr/lib/python3/dist-packages/ffcx/codegeneration/jit.py", line 260, in _compile_objects
    _, code_body = ffcx.compiler.compile_ufl_objects(ufl_objects, prefix=module_name, options=options)

  File "/usr/lib/python3/dist-packages/ffcx/compiler.py", line 102, in compile_ufl_objects
    ir = compute_ir(analysis, object_names, prefix, options, visualise)

  File "/usr/lib/python3/dist-packages/ffcx/ir/representation.py", line 197, in compute_ir
    irs = [_compute_integral_ir(fd, i, analysis.element_numbers, integral_names, finite_element_names,

  File "/usr/lib/python3/dist-packages/ffcx/ir/representation.py", line 197, in <listcomp>
    irs = [_compute_integral_ir(fd, i, analysis.element_numbers, integral_names, finite_element_names,

  File "/usr/lib/python3/dist-packages/ffcx/ir/representation.py", line 492, in _compute_integral_ir
    integral_ir = compute_integral_ir(itg_data.domain.ufl_cell(), itg_data.integral_type,

  File "/usr/lib/python3/dist-packages/ffcx/ir/integral.py", line 84, in compute_integral_ir
    mt_table_reference = build_optimized_tables(

  File "/usr/lib/python3/dist-packages/ffcx/ir/elementtables.py", line 361, in build_optimized_tables
    t = get_ffcx_table_values(quadrature_rule.points, cell,

  File "/usr/lib/python3/dist-packages/ffcx/ir/elementtables.py", line 124, in get_ffcx_table_values
    entity_points = map_integral_points(points, integral_type, cell, entity)

  File "/usr/lib/python3/dist-packages/ffcx/ir/representationutils.py", line 92, in map_integral_points
    assert points.shape[1] == tdim - 1

AssertionError

I am currently using DG0 elements for internal variables and CG1 for the displacement, but I would like to raise the interpolation degree so that it would require Quadrature elements for the internal variables.

Do you have any guidance on how to resolve this issue?
Sincerely,
Paul

Hello Paul,
this is related to this issue

which should be fixed in v0.7, see for instance this plasticity demo:

Elasto-plastic analysis of a 2D von Mises material — Computational Mechanics Numerical Tours with FEniCSx

However, there were still some issues left (see below) with basix Quadrature elements in v0.7 which are fixed in the current v0.8 version

1 Like