Helmholtz Equation

28. Helmholtz Equation#

Inserting a time harmonic right hand side \(f(x,t) = f(x) e^{i \omega t}\) into the wave equation leads to a time-harmonic solution solution \(u(x,t) = u(x) e^{i \omega t}\) satisfying

\[ \frac{\partial^2}{\partial t^2} u(x) e^{i \omega t} - \Delta u(x) e^{i \omega t} = f(x) e^{i \omega t}. \]

This leads to the Helmholtz equation (also known as frequency domain wave equation)

\[ -\Delta u - \omega^2 u = f. \]

We consider Dirichlet (hard) boundary conditions

\[ u(x) = 0 \]

and Robin (absorbing) boundary conditions

\[ \frac{\partial u}{\partial n} - i \omega u = 0 \qquad \text{ on } \Gamma_R \]

The weak form is

\[ \int_\Omega \nabla u \nabla v - \omega^2 u v - i \omega \int_{\Gamma_R} u v = \int_\Omega f v \]
from ngsolve import *
from ngsolve.webgui import Draw
mesh = Mesh(unit_square.GenerateMesh(maxh=0.05))
fes = H1(mesh, order=5, complex=True)
u,v = fes.TnT()

omega = 2*pi*10

a = BilinearForm(fes)
a += (grad(u)*grad(v)-omega**2*u*v)*dx
a += -1j*omega*u*v*ds
a.Assemble()

source = exp(-50**2*((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5)))
f = LinearForm(source*v*dx(bonus_intorder=5)).Assemble()

gfu = GridFunction(fes)
gfu.vec.data = a.mat.Inverse(fes.FreeDofs()) * f.vec
Draw (1e3*gfu, mesh, order=3, animate_complex=True, deformation=True);

28.1. Incoming beam from the left side#

we model an incoming beam (e.g. laser beam) from the left boundary by means of the boundary condition

\[ \frac{\partial u}{\partial n} - i \omega u = g \]
from netgen.occ import *
shape = MoveTo(-1,-1).Rectangle (2,2).Face()
shape.edges.Min(X).name="left"
shape.edges.Min(Y).name="bottom"
shape.edges.Max(X).name="right"
shape.edges.Max(Y).name="top"
circ = Circle ( (0.6, 0.0), 0.07).Face()
rect = MoveTo(-0.2,-0.4).Rotate(45).Rectangle(1,0.1).Face()
# shape = shape-circ
# shape = shape-rect
mesh = Mesh (OCCGeometry( shape, dim=2).GenerateMesh(maxh=0.05)).Curve(3)
Draw (shape);
fes = H1(mesh, order=5, complex=True)
u,v = fes.TnT()

a = BilinearForm(fes)
f = LinearForm(fes)

omega = 20*pi
outer = "left|right|bottom|top"
a += grad(u)*grad(v)*dx-omega**2*u*v*dx - 1j*omega*u*v*ds(outer)
f = LinearForm(fes)

incoming = 100*exp(-5**2*y*y)
f += incoming*v * ds("left")

a.Assemble()
f.Assemble()

gfu = GridFunction(fes)
gfu.vec.data = a.mat.Inverse(fes.FreeDofs()) * f.vec
Draw (gfu, order=3, animate_complex=True);