I’ve been trying to implement solvers for Maxwell’s equations (both scattering and eigenvalue problems) in 2 and 3 dimensions. Everything worked fine in 2D (including complex domains, eigenvector sources and PML).
However, in 3D, even small problems seem to take much longer to solve than I would expect. I’m guessing I’m doing something wrong.
one big difference is that in 3D you have “many” negative eigenvalues, evaluating the biform with any gradient field leads to the negative sign.
A simple method is the “shifted Laplacian” preconditioning: Setup a second, artificial biform with volume damping, build the preconditioner for the artificial problem, and use it to solve the original equation:
apre = ngsolve.BilinearForm(fes)
apre += p * (ngsolve.curl(u) * ngsolve.curl(w)) * ngsolve.dx
apre += -(1+1j)*(k0 ** 2) * q * (u * w) * ngsolve.dx
pre = ngsolve.Preconditioner(apre, "bddc")
Be careful to choose the sign of the imaginary part of the L2-coefficient according to damping, when you have also physical damping.
It still takes many iterations, and you may have to play with the damping coefficient.
Thanks for the input, Joachim! I’ll go thru the references you indicated and see whether I can improve the code. Our use case is for topological optimization, so any gains in a single run is a big advantage. We currently use COMSOL, but we’d love to use an open-source alternative!