Tensor field interpolation

Hi everybody!

I am quite afraid I might have an incredibly silly question, but I am at a loss and I have failed to find an answer in the documentation or other posts.

I am trying to interpolate a tensor field on a function space so later I can use it in an UFL form together with solution to a diffusion equation and integrate an expression involving them both over the domain. So basically the tensor field is a user input hence I would like to set it with some Python function. However when I try the following:

import dolfinx
import dolfinx.fem.function
import dolfinx.fem.petsc
import ufl
import numpy as np
from mpi4py import MPI

domain = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 8, 8)
V = dolfinx.fem.functionspace(domain, ("Lagrange", 1, (2, 2)))
J = dolfinx.fem.Function(V)

def my_tensor_field(x):
    return np.zeros((2,2))

J.interpolate(my_tensor_field)

Things fail with:

Traceback (most recent call last):
  File "/path/path/path/miniconda3/envs/fenicsx-env/lib/python3.12/site-packages/dolfinx/fem/function.py", line 492, in interpolate
    _interpolate(u, cells)
  File "/path/path/path/miniconda3/envs/fenicsx-env/lib/python3.12/functools.py", line 909, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/path/path/path//miniconda3/envs/fenicsx-env/lib/python3.12/site-packages/dolfinx/fem/function.py", line 455, in _interpolate
    self._cpp_object.interpolate(u, cells, nmm_interpolation_data)  # type: ignore
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: interpolate(): incompatible function arguments. The following argument types are supported:
    1. interpolate(self, f: ndarray[dtype=float64, writable=False, shape=(*), order='C'], cells: ndarray[dtype=int32, writable=False, shape=(*), order='C']) -> None
    2. interpolate(self, f: ndarray[dtype=float64, writable=False, shape=(*, *), order='C'], cells: ndarray[dtype=int32, writable=False, shape=(*), order='C']) -> None
    3. interpolate(self, u: dolfinx.cpp.fem.Function_float64, cells: ndarray[dtype=int32, writable=False, shape=(*), order='C'], cell_map: ndarray[dtype=int32, writable=False, shape=(*), order='C'], nmm_interpolation_data: tuple[ndarray[dtype=int32, writable=False, shape=(*), order='C'], ndarray[dtype=int32, writable=False, shape=(*), order='C'], ndarray[dtype=float64, writable=False, shape=(*), order='C'], ndarray[dtype=int32, writable=False, shape=(*), order='C']]) -> None
    4. interpolate(self, expr: dolfinx.cpp.fem.Expression_float64, cells: ndarray[dtype=int32, writable=False, order='C'], expr_mesh: dolfinx.cpp.mesh.Mesh_float64, cell_map: ndarray[dtype=int32, writable=False, order='C']) -> None

Invoked with types: dolfinx.cpp.fem.Function_float64, function, ndarray, dolfinx.fem.function.PointOwnershipData

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/path/path/path//GeometricSensitivity/FEniCSx/Diffusion2D/mwe.py", line 15, in <module>
    J.interpolate(my_tensor_field)
  File "/path/path/path//miniconda3/envs/fenicsx-env/lib/python3.12/site-packages/dolfinx/fem/function.py", line 497, in interpolate
    self._cpp_object.interpolate(np.asarray(u(x), dtype=self.dtype), cells)  # type: ignore
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: Interpolation data has the wrong shape/size.

Clearly I am doing something wrong :-/

Also what confuses me is that:

import dolfinx
import dolfinx.fem.function
import dolfinx.fem.petsc
import ufl
import numpy as np
from mpi4py import MPI

domain = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 8, 8)
V = dolfinx.fem.functionspace(domain, ("Lagrange", 1, (2, 1)))
J = dolfinx.fem.Function(V)

def my_tensor_field(x):
    return np.zeros((2,1))

J.interpolate(my_tensor_field)

seems to work perfectly fine! And I have no clue why.

Basically it means I must be missing something very fundamental about how the interpolation works and what output form my_tensor_field is supposed to provide to the interpolate method.

I am using Dolfinx 0.8.0.

Thanks for the help!

See here

1 Like

@bleyerj Thanks a lot!