6.2. Perfectly matched layers in NGSolve#
In NGSolve
PMLs are implemented as additional mesh transformation. First a PML
object is generated.
from ngsolve import *
from ngsolve.webgui import Draw
pml_cart = pml.Cartesian((0,0),(0.5,0.5),3j)
pml.Cartesian((xmin, ymin), (xmax,ymax),alpha)
generates a cartesian PML with a complex scaling outside of the rectangle \(\Omega_{\mathrm {int}}\) defined by xmin,ymin,xmax,ymax
with complex coordinate stretching 1+alpha
.
Calling the mapping yields the complex scaled point:
pml_cart(1,0), pml_cart(3,1)
( (1,1.5)
(0,0),
(3,7.5)
(1,1.5))
The PML
class also offers the scaling and its Jacobian and determinant as a CoefficientFunction
mesh = Mesh(unit_square.GenerateMesh(maxh=0.1))
Draw(pml_cart.PML_CF.real,mesh,vectors=True)
Draw(pml_cart.PML_CF.imag,mesh,vectors=True)
Draw(pml_cart.Det_CF.real,mesh)
Draw(pml_cart.Det_CF.imag,mesh)
Draw(pml_cart.Jac_CF.real,mesh)
Draw(pml_cart.Jac_CF.imag,mesh)
BaseWebGuiScene
To set a PML to a mesh one may use Mesh.SetPML(PML,domain)
mesh.SetPML(pml_cart,'.*')
Assembling a matrix will now integrate over the “complex” mesh:
fes = H1(mesh, complex = True)
u,v = fes.TnT()
bfm = BilinearForm(u*v*dx).Assemble()
print(bfm.mat[0,0])
(0.0008333333333333365+0.0012500000000000048j)
Different types of PMLs#
There exist different types of scalings e.g., PML.Radial
, PML.HalfSpace
, PML.BrickRadial
pml_rad = pml.Radial((0,0),0.2)
Draw(pml_rad.PML_CF.imag,mesh,order=5)
BaseWebGuiScene
pml_half = pml.HalfSpace((0.5,0),(2,1))
Draw(pml_half.PML_CF.imag,mesh,order=5)
BaseWebGuiScene
pml_brickrad = pml.BrickRadial((0.2,0.2),(0.4,0.8),(0.3,0.3))
Draw(pml_brickrad.PML_CF.imag,mesh,order=5)
BaseWebGuiScene
Combining PMLs#
PMLs can be combined using +
:
sumpml = pml.HalfSpace((0.5,0),(1,0))+pml.HalfSpace((0,0.5),(0.5,1))
Draw(sumpml.PML_CF.imag,mesh,order=5)
BaseWebGuiScene
This can e.g., be used to create a cartesian scaling with different strength in each direction
cart_pml_ani = pml.HalfSpace((0.5,0),(1,0))+pml.HalfSpace((0,0.5),(0,1),5j)
Draw(cart_pml_ani.PML_CF.imag,mesh,order=5)
BaseWebGuiScene
PMLs can also be tensorized using CompoundPML
pml3d = pml.Compound(sumpml,pml.Cartesian((0.2),(0.7)))
mesh = Mesh(unit_cube.GenerateMesh(maxh=0.1))
Draw(pml3d.PML_CF.imag,mesh)
BaseWebGuiScene