Incompatible function arguments for assemble_scalar

I am new to FEniCS and am working through and modifying some of the example codes for both FEniCSx and comet-FEniCS. I was attempting to track the center of mass of a deforming body by integrating the spatial coordinates over the body. When I call assemble_scalar on the Form containing the integral, I get an error stating there were incompatible function arguments and that suggested there could be files that were not included. I am using the Docker image of the real build of DOLFINx in Jupyter Lab.

Here is a MWE of the issue:

import numpy as np
import ufl

from petsc4py import PETSc
from mpi4py import MPI
from dolfinx import fem, mesh, plot

domain = mesh.create_box(MPI.COMM_WORLD,[[0.0,0.0,0.0],[1,1,1]], [1,1,1],mesh.CellType.hexahedron)
dx = ufl.Measure("dx",domain=domain)

x = ufl.SpatialCoordinate(domain)
Mx = x[0]*dx
My = x[1]*dx
Mz = x[2]*dx
print(type(Mx))
print(fem.assemble_scalar(Mx))

This yields the error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [3], in <cell line: 16>()
     14 Mz = x[2]*dx
     15 print(type(Mx))
---> 16 print(fem.assemble_scalar(Mx))

File /usr/local/dolfinx-real/lib/python3.8/dist-packages/dolfinx/fem/assemble.py:128, in assemble_scalar(M, constants, coeffs)
    105 def assemble_scalar(M: FormMetaClass, constants=None, coeffs=None):
    106     """Assemble functional. The returned value is local and not
    107     accumulated across processes.
    108 
   (...)
    126 
    127     """
--> 128     constants = constants or _pack_constants(M)
    129     coeffs = coeffs or _pack_coefficients(M)
    130     return _cpp.fem.assemble_scalar(M, constants, coeffs)

TypeError: pack_constants(): incompatible function arguments. The following argument types are supported:
    1. (arg0: dolfinx::fem::Form<double>) -> numpy.ndarray[numpy.float64]
    2. (arg0: dolfinx::fem::Expression<double>) -> numpy.ndarray[numpy.float64]
    3. (arg0: dolfinx::fem::Form<float>) -> numpy.ndarray[numpy.float32]
    4. (arg0: dolfinx::fem::Expression<float>) -> numpy.ndarray[numpy.float32]
    5. (arg0: dolfinx::fem::Form<std::complex<double> >) -> numpy.ndarray[numpy.complex128]
    6. (arg0: dolfinx::fem::Expression<std::complex<double> >) -> numpy.ndarray[numpy.complex128]

Invoked with: Form([Integral(Indexed(SpatialCoordinate(Mesh(VectorElement(FiniteElement('Q', hexahedron, 1), dim=3), 2)), MultiIndex((FixedIndex(0),))), 'cell', Mesh(VectorElement(FiniteElement('Q', hexahedron, 1), dim=3), 2), 'everywhere', {}, None)])

Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,
<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic
conversions are optional and require extra headers to be included
when compiling your pybind11 module.

Is this a misunderstanding of how to calculate body integrals in the context of Forms, or am I mistranslating something from FEniCS to FEniCSx?

Thanks so much!

As shown in the demo: dolfinx/test_assemble_submesh.py at 7b3e22e95f62f827a4e9d3eb5124f53c5e2148f3 · FEniCS/dolfinx · GitHub
And in the tutorial: A known analytical solution — FEniCSx tutorial
you need to call dolfinx.fem.form(Mx) and call assemble scalar on this to assemble the form.

The reason for this is to ensure the inputs to Mx are Pre defined (to avoid extra compilation time)

1 Like