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!