It took me quite a while to understand why one of my code was not working. I managed to find the source of the issue. It is quite unclear to me if the issue comes from ufl or the use of create_real_functionspace but it seems that bessel function can not be used with complex argument. Here is a MWE:
import dolfinx
import ufl
from scifem import create_real_functionspace
from mpi4py import MPI
from scipy.special import jv as jv_scipy
msh = dolfinx.mesh.create_rectangle(comm=MPI.COMM_WORLD, points=((0., 0.), (1., 1.)), n=(1, 1), cell_type=dolfinx.mesh.CellType.triangle)
R = create_real_functionspace(msh)
x = dolfinx.fem.Function(R)
f = dolfinx.fem.Function(R)
x_value = 12.0j
x = dolfinx.fem.Function(R)
x.x.array[:] = x_value
x.x.scatter_forward()
def my_function(x):
jv = ufl.bessel_J if isinstance(x, ufl.core.expr.Expr) else jv_scipy
return jv(0, x)
f.interpolate(dolfinx.fem.Expression(my_function(x), R.element.interpolation_points))
print(f.x.array[:],' / ',my_function(x_value)) # [1.+0.j] / (18948.925349296307+0j)
We see that the value is not the same as the one returned by the scipy implementation of the Bessel function.
I’m quite unsure whether I should post that to the ufl issue tracker, let me know if that is the case.
Unfortunately, it looks like the standard C library does not have an implementation of bessel functions of the first kind for complex arguments: IBM Documentation
You can try this with something like
#include <stdio.h>
#include <math.h>
#include <complex.h>
int main() {
double complex x = 12.0*I;
int n = 0;
double complex result = jn(n, x);
printf("J%d(%.1f + %.1fi) = %.1f + %.1fi\n", n, x, result);
return 0;
}