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!
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)
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.
I work with the same PDE and I use Fenics 2019.1.0 as well.
We use the FunctionSpace this way
P1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
# # Define 2D-Real function space to substitute for Complex space
V = FunctionSpace(mesh, P1 * P1) # NOTE: V.sub(0) and V.sub(1) are the subspaces
and take the Trial and test functions as tuples from V i.e
Wow thank you very very much, it really helped me out a lot!
Can you post your weak formulation so I can compare it?
I’m not sure if I have done it right.
Maybe one question here:
I am having a similar problem and have my FunctionSpace set up like in your examples above.
However, I am using SLEPcEigenSolver and it looks like the complex part of the eigenvalue is always zero. (I’ll have to sit for an MWE…)
Has anyone here ever successfully obtained complex eigenvalues from a real-valued problem with dolfin.SLEPcEigenSolver?
Is it possible to find this example? When i klick the link i only get a 404 response code. It would really help me a lot to see other peoples solutions to this.
RN i assemble all of the boundary conditions myself. I would love to know another way of doing it
For reference, here’s an involved example of solving a complex-valued Helmholtz scattering problem with Perfectly Matched Layers for reference. All the complex-arithmetic in the variational forms (UFL forms) is handled by way of a complex class.
should get it working for you (define SLEPC_DIR likewise if needed).
If you need more fine control (e.g. different petsc versions) you can point PETSC_DIR at other locations below /usr/lib/petscdir/.
The FEniCS build (python modules) are placed in ${PETSC_DIR}/lib/python3/dist-packages/. If dolfinx is not located there, then it hasn’t been built for that version of PETSc.