Dolfinx, 'Failure to conjugate test function in complex Form'

I ran into the error ‘ArityMismatch: Failure to conjugate test function in complex Form’ when solving the LinearProblem. I met the same error before when I used f*v instead of inner(f,v) for integral in complex-mode, for a Langrange scalar FunctionSpace.
However, this time I’m using a N1curl vector FunctionSpace and I have (properly?) use ufl.inner for integral. Thanks if someone can tell me where’s my mistake.

import meshio
import numpy as np
import dolfinx
import ufl
from mpi4py import MPI
from dolfinx import (Function, FunctionSpace, UnitSquareMesh,
has_petsc_complex)
from dolfinx.fem.assemble import assemble_scalar
from dolfinx.io import XDMFFile
from ufl import FiniteElement, FacetNormal, TestFunction, TrialFunction, dx, grad, inner, curl, cross

with dolfinx.io.XDMFFile(MPI.COMM_WORLD, ‘./Radiation/Cube_cf.xdmf’, ‘r’) as infile:
mesh = infile.read_mesh(name=‘Grid’)
ct = infile.read_meshtags(mesh, name=‘Grid’)
mesh.topology.create_connectivity(mesh.topology.dim, mesh.topology.dim-1)
with dolfinx.io.XDMFFile(MPI.COMM_WORLD, ‘./Radiation/Cube_mf.xdmf’, ‘r’) as infile:
ft = infile.read_meshtags(mesh, name=‘Grid’)

print(‘has_pestc_complex:’,has_petsc_complex)
elem_type = FiniteElement(‘N1curl’, mesh.ufl_cell(), 1)
V = FunctionSpace(mesh, elem_type)

#define current(J) function
eps = 1e-4

def Delta(x):
values = np.zeros(x.shape)
values[0] = 0
values[1] = 0
values[2] = eps/np.pi/(np.linalg.norm(x, axis=0)* *2 + eps**2)
return values

J = Function(V)
J.interpolate(Delta)
with XDMFFile(MPI.COMM_WORLD, “./Radiation/J.xdmf”, “w”,
encoding=XDMFFile.Encoding.HDF5) as file:
file.write_mesh(mesh)
file.write_function(J)

#construct the problem
u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
x = ufl.SpatialCoordinate(mesh)
n = ufl.FacetNormal(mesh)
a = ufl.dot(v, u)*dx
L = ufl.dot(v, J)*dx
u = Function(V)
problem = dolfinx.fem.LinearProblem(a, L, u=u, petsc_options={“ksp_type”: “preonly”, “pc_type”: “lu”})
problem.solve()

The xdmf mesh files are not supported to be upload, they are tetraherons mesh of a Cube.

The error still shows when I change from dot to inner

For further posts, please use 3x ` encapsulation for formatting, to ensure that the code is executable with a copy-paste.
The problem is that you are supplying v as the first input to your form. It as to be the second input.
I.e. the following minimal code shows how a working example would look like

import numpy as np
from mpi4py import MPI
from dolfinx import (Function, FunctionSpace, UnitCubeMesh,
has_petsc_complex)
from dolfinx.fem import LinearProblem
import ufl 

print("has_pestc_complex:",has_petsc_complex)
mesh = UnitCubeMesh(MPI.COMM_WORLD, 10, 10, 10)
elem_type = ufl.FiniteElement("N1curl", mesh.ufl_cell(), 1)
V = FunctionSpace(mesh, elem_type)

# Define current(J) function
eps = 1e-4

def Delta(x):
    values = np.zeros(x.shape)
    values[0] = 0
    values[1] = 0
    values[2] = eps/np.pi/(np.linalg.norm(x, axis=0)**2 + eps**2)
    return values

J = Function(V)
J.interpolate(Delta)
#construct the problem
u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
x = ufl.SpatialCoordinate(mesh)
n = ufl.FacetNormal(mesh)
a = ufl.inner(u, v)*ufl.dx
L = ufl.inner(J, v)*ufl.dx
u = Function(V)
problem = LinearProblem(a, L, u=u, petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
problem.solve()
4 Likes

Thanks dokken ! The code is running now.
Sorry for my poor writing, I’ll definitely use 3x` the next time.

Good evening,

I’m trying to run the demo of poisson equation using JupyterLab and i have installed Dolfinx via Docker.
i have encountered the same errorType by implementing the code i found in the FEniCSx Tutorial and i have been searching what i’ve been missing and looked through the Changelog too but that didn’t get me anywhere.
i have tried both dot and inner functions and none of them did work as well.
i wish if you could help me with that.

FEniCSx Tutorial:

the Code:

from mpi4py import MPI
from dolfinx import mesh
domain = mesh.create_unit_square(MPI.COMM_WORLD, 8, 8, mesh.CellType.quadrilateral)

from dolfinx.fem import FunctionSpace
V = FunctionSpace(domain, ("CG", 1))

from dolfinx import fem
uD = fem.Function(V)
uD.interpolate(lambda x: 1 + x[0]**2 + 2 * x[1]**2)

import numpy
# Create facet to cell connectivity required to determine boundary facets
tdim = domain.topology.dim
fdim = tdim - 1
domain.topology.create_connectivity(fdim, tdim)
boundary_facets = numpy.flatnonzero(mesh.compute_boundary_facets(domain.topology))

boundary_dofs = fem.locate_dofs_topological(V, fdim, boundary_facets)
bc = fem.dirichletbc(uD, boundary_dofs)

import ufl
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)

from petsc4py.PETSc import ScalarType
f = fem.Constant(domain, ScalarType(-6))

a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
L = f * v * ufl.dx

problem = fem.petsc.LinearProblem(a, L, bcs=[bc], petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
uh = problem.solve()

the Error that i get:

---------------------------------------------------------------------------
ArityMismatch                             Traceback (most recent call last)
Input In [26], in <cell line: 32>()
     29 a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
     30 L = f * v * ufl.dx
---> 32 problem = fem.petsc.LinearProblem(a, L, bcs=[bc], petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
     33 uh = problem.solve()

File /usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/petsc.py:508, in LinearProblem.__init__(self, a, L, bcs, u, petsc_options, form_compiler_params, jit_params)
    505 self._a = _create_form(a, form_compiler_params=form_compiler_params, jit_params=jit_params)
    506 self._A = create_matrix(self._a)
--> 508 self._L = _create_form(L, form_compiler_params=form_compiler_params, jit_params=jit_params)
    509 self._b = create_vector(self._L)
    511 if u is None:
    512     # Extract function space from TrialFunction (which is at the
    513     # end of the argument list as it is numbered as 1, while the
    514     # Test function is numbered as 0)

File /usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/forms.py:139, in form(form, dtype, form_compiler_params, jit_params)
    136         return list(map(lambda sub_form: _create_form(sub_form), form))
    137     return form
--> 139 return _create_form(form)

File /usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/forms.py:134, in form.<locals>._create_form(form)
    131 """Recursively convert ufl.Forms to dolfinx.fem.Form, otherwise
    132 return form argument"""
    133 if isinstance(form, ufl.Form):
--> 134     return _form(form)
    135 elif isinstance(form, collections.abc.Iterable):
    136     return list(map(lambda sub_form: _create_form(sub_form), form))

File /usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/fem/forms.py:108, in form.<locals>._form(form)
    105 if mesh is None:
    106     raise RuntimeError("Expecting to find a Mesh in the form.")
--> 108 ufcx_form, module, code = jit.ffcx_jit(mesh.comm, form,
    109                                        form_compiler_params=form_compiler_params,
    110                                        jit_params=jit_params)
    112 # For each argument in form extract its function space
    113 V = [arg.ufl_function_space()._cpp_object for arg in form.arguments()]

File /usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/jit.py:56, in mpi_jit_decorator.<locals>.mpi_jit(comm, *args, **kwargs)
     51 @functools.wraps(local_jit)
     52 def mpi_jit(comm, *args, **kwargs):
     53 
     54     # Just call JIT compiler when running in serial
     55     if comm.size == 1:
---> 56         return local_jit(*args, **kwargs)
     58     # Default status (0 == ok, 1 == fail)
     59     status = 0

File /usr/local/dolfinx-complex/lib/python3.8/dist-packages/dolfinx/jit.py:204, in ffcx_jit(ufl_object, form_compiler_params, jit_params)
    202 # Switch on type and compile, returning cffi object
    203 if isinstance(ufl_object, ufl.Form):
--> 204     r = ffcx.codegeneration.jit.compile_forms([ufl_object], parameters=p_ffcx, **p_jit)
    205 elif isinstance(ufl_object, ufl.FiniteElementBase):
    206     r = ffcx.codegeneration.jit.compile_elements([ufl_object], parameters=p_ffcx, **p_jit)

File /usr/local/lib/python3.9/dist-packages/ffcx/codegeneration/jit.py:168, in compile_forms(forms, parameters, cache_dir, timeout, cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries)
    165     for name in form_names:
    166         decl += form_template.format(name=name)
--> 168     impl = _compile_objects(decl, forms, form_names, module_name, p, cache_dir,
    169                             cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries)
    170 except Exception:
    171     # remove c file so that it will not timeout next time
    172     c_filename = cache_dir.joinpath(module_name + ".c")

File /usr/local/lib/python3.9/dist-packages/ffcx/codegeneration/jit.py:232, in _compile_objects(decl, ufl_objects, object_names, module_name, parameters, cache_dir, cffi_extra_compile_args, cffi_verbose, cffi_debug, cffi_libraries)
    228 import ffcx.compiler
    230 # JIT uses module_name as prefix, which is needed to make names of all struct/function
    231 # unique across modules
--> 232 _, code_body = ffcx.compiler.compile_ufl_objects(ufl_objects, prefix=module_name, parameters=parameters)
    234 ffibuilder = cffi.FFI()
    235 ffibuilder.set_source(module_name, code_body, include_dirs=[ffcx.codegeneration.get_include_path()],
    236                       extra_compile_args=cffi_extra_compile_args, libraries=cffi_libraries)

File /usr/local/lib/python3.9/dist-packages/ffcx/compiler.py:98, in compile_ufl_objects(ufl_objects, object_names, prefix, parameters, visualise)
     96 # Stage 1: analysis
     97 cpu_time = time()
---> 98 analysis = analyze_ufl_objects(ufl_objects, parameters)
     99 _print_timing(1, time() - cpu_time)
    101 # Stage 2: intermediate representation

File /usr/local/lib/python3.9/dist-packages/ffcx/analysis.py:75, in analyze_ufl_objects(ufl_objects, parameters)
     72     else:
     73         raise TypeError("UFL objects not recognised.")
---> 75 form_data = tuple(_analyze_form(form, parameters) for form in forms)
     76 for data in form_data:
     77     elements += data.unique_sub_elements

File /usr/local/lib/python3.9/dist-packages/ffcx/analysis.py:75, in <genexpr>(.0)
     72     else:
     73         raise TypeError("UFL objects not recognised.")
---> 75 form_data = tuple(_analyze_form(form, parameters) for form in forms)
     76 for data in form_data:
     77     elements += data.unique_sub_elements

File /usr/local/lib/python3.9/dist-packages/ffcx/analysis.py:156, in _analyze_form(form, parameters)
    153 complex_mode = "_Complex" in parameters["scalar_type"]
    155 # Compute form metadata
--> 156 form_data = ufl.algorithms.compute_form_data(
    157     form,
    158     do_apply_function_pullbacks=True,
    159     do_apply_integral_scaling=True,
    160     do_apply_geometry_lowering=True,
    161     preserve_geometry_types=(ufl.classes.Jacobian,),
    162     do_apply_restrictions=True,
    163     do_append_everywhere_integrals=False,  # do not add dx integrals to dx(i) in UFL
    164     complex_mode=complex_mode)
    166 # Determine unique quadrature degree, quadrature scheme and
    167 # precision per each integral data
    168 for id, integral_data in enumerate(form_data.integral_data):
    169     # Iterate through groups of integral data. There is one integral
    170     # data for all integrals with same domain, itype, subdomain_id
   (...)
    176 
    177     # Extract precision

File /usr/local/lib/python3.9/dist-packages/ufl/algorithms/compute_form_data.py:407, in compute_form_data(form, do_apply_function_pullbacks, do_apply_integral_scaling, do_apply_geometry_lowering, preserve_geometry_types, do_apply_default_restrictions, do_apply_restrictions, do_estimate_degrees, do_append_everywhere_integrals, complex_mode)
    403 # TODO: This is a very expensive check... Replace with something
    404 # faster!
    405 preprocessed_form = reconstruct_form_from_integral_data(self.integral_data)
--> 407 check_form_arity(preprocessed_form, self.original_form.arguments(), complex_mode)  # Currently testing how fast this is
    409 # TODO: This member is used by unit tests, change the tests to
    410 # remove this!
    411 self.preprocessed_form = preprocessed_form

File /usr/local/lib/python3.9/dist-packages/ufl/algorithms/check_arities.py:177, in check_form_arity(form, arguments, complex_mode)
    175 def check_form_arity(form, arguments, complex_mode=False):
    176     for itg in form.integrals():
--> 177         check_integrand_arity(itg.integrand(), arguments, complex_mode)

File /usr/local/lib/python3.9/dist-packages/ufl/algorithms/check_arities.py:170, in check_integrand_arity(expr, arguments, complex_mode)
    168 for arg, conj in arg_tuples:
    169     if arg.number() == 0 and not conj:
--> 170         raise ArityMismatch("Failure to conjugate test function in complex Form")
    171     elif arg.number() > 0 and conj:
    172         raise ArityMismatch("Argument {0} is spuriously conjugated in complex Form".format(arg))

ArityMismatch: Failure to conjugate test function in complex Form

Changing this to


L = ufl.inner(f, v)* ufl.dx

Should resolve the issue.

2 Likes

Thank you so much. it did work.

Hi,
I have the same problem as Hamdi_Kahloum.
However, it wasn’t fixed by changing L to

L = ufl.inner(f, v)* ufl.dx

Then you need to provide a minimal example that reproduces the issue.

Hello
I’m trying to run the example in the tutorial of Fenicsx. It did well except cannot plotting the image of results
So, can you help me to solve this problem?
Thank you so much for your helps