Solving complex-valued PDE

#1

Hi,
I’m trying to solve the helmholtz equation in its form Laplace§+k^2*p = 0, where p is a complex-valued quantity. I have a 3D Box mesh and following boundary conditions.
boundary_conditions = {
0: {“Neumann”: a_val * v_s[0]}, # 0 left boundary
1: {“Neumann”: a_val * v_s[1]}, # 1 lower boundary
2: {“Robin”: (a_val * Y_right, -1 * Z_right * v_s[2])}, # 2 right boundary
3: {“Neumann”: a_val * v_s[3]}, # 3 upper boundary
4: {“Neumann”: a_val * v_s[4]}, # 4 front boundary
5: {“Neumann”: a_val * v_s[5]}, # 5 back boundary
}
where Y_right and Z_right are real valued quantities, a_val and the list v_s has a complex values. I’m then collecting my Neumann and Robin boundary conditions in lists and evalaute them.
bc = []
integrals_n = [] # list for NBC
integrals_ra = [] # list for RBC
integrals_rl = [] # list for RBC
j = complex(0, 1)
for i in boundary_conditions:
# collect Neumann integrals
if “Neumann” in boundary_conditions[i]:
if boundary_conditions[i][“Neumann”] != 0:
print(“Neumann Integral added”)
g = boundary_conditions[i][“Neumann”]
integrals_n.append(df.inner(g, v) * df.ds(i))
# Collect Robin integrals, can be split up in two lists
if “Robin” in boundary_conditions[i]:
if boundary_conditions[i][“Robin”]:
print(“Robin Integral added”)
r, s = boundary_conditions[i][“Robin”]
integrals_ra.append(r * p * v * df.ds(i))
integrals_rl.append(r * s * v * df.ds(i))
Afterwards i’m building my left and right side and solve it.
left_side = -1 * (df.inner(df.grad§, df.grad(v)) - (k ** 2) * v * p) * df.dx - sum(integrals_ra)
right_side = df.Constant(0) * v * df.dx + sum(integrals_n) - sum(integrals_rl)

u = df.Function(function_space)

df.solve(left_side == right_side, u, bc)
Since p is a complex valued quantity, i’m expecting a complex solution, but i’m only getting the following error message:
ufl.log.UFLException: Unexpected complex value in real expression.
I’m not able to figure out why this is happening. I was trying to do it like in here:


But none of this is working and i wasn’t able to find anything on this forum, so i’m hoping anyone of you can help me.
There are also only Neumann and Robin boundary conditions, therefore i’m not sure how to handle it properly.
Any little help is highly appreciated!

#2

Which version of fenics are you using?

1 Like
#3

I’m using FEniCS version 2019.1.0, sorry I forgot to mention it.

#4

The example you’re following comes from dolfin-x, the development version of dolfin. dolfin 2019.1 does not support complex numbers. You’ll need to build dolfin-x from source.

(an alternative of course is to split the real and imaginary parts and solve the simultaneous system of 2 real equations using a MixedFunctionSpace)

1 Like
#5

Thank you very much, is there an example of how to calculate the real and imaginary parts using a MixedFunctionSpace?

#6

You’ll need to use your own maths to split the equations. But there are examples of MixedFunctionSpaces

e.g. Stokes equations (solving for u and p),
https://fenicsproject.org/docs/dolfin/2019.1.0/python/demos/stokes-iterative/demo_stokes-iterative.py.html
/usr/share/dolfin/demo-python/documented/stokes-iterative/

Mixed Poisson
https://fenicsproject.org/docs/dolfin/2019.1.0/python/demos/mixed-poisson/demo_mixed-poisson.py.html

also
/usr/share/dolfin/demo-python/undocumented/mixed-poisson-sphere/demo_mixed-poisson-sphere.py

1 Like
#7

Thank you very much that really helped me out a lot, i’m currently trying to figure out how to build dolfin-x from source, but i will try it with the MixedFunctionSpace.