from netgen.occ import *
from ngsolve import *
from ngsolve.webgui import Draw
from ngsolve.bem import *
from ngsolve import Projector, Preconditioner
from ngsolve.krylovspace import CG
keys: electrostatics, homogeneous Dirichlet bvp, single layer potential \(V\)
Dirichlet Laplace Indirect Method#
We consider the Dirichlet boundary value problem
Let us choose the following ansatz for the solution \(u\in H^1(\Omega)\) (indirect ansatz)
Define the geometry \(\Omega \subset \mathbb R^3\) and create a mesh:
sp = Sphere( (0,0,0), 1)
mesh = Mesh( OCCGeometry(sp).GenerateMesh(maxh=0.3)).Curve(3)
Create test and trial function finite element spaces for \(H^{-\frac12}(\Gamma)\) according to the given mesh:
fesL2 = SurfaceL2(mesh, order=3, dual_mapping=True)
u,v = fesL2.TnT()
Boundary Integral Equation
We carefully apply the Dirichlet trace on the ansatz for \(u\) and get an integral equation for the unknown density \(j\in H^{-\frac12}(\Gamma)\). The integral equation may be read as follows: determine \(j\) such that
Details
For any \(u_j, v_i \in H^{-\frac12}(\Gamma)\), the single layer potential operator is implemented as follows
You may assemble \(V\) it by
V = LaplaceSL(u*ds)*v*ds
Compute the given Dirichlet data \(m\), the right hand side and the matrix \(\mathrm V\) (single layer potential operator).
m = 1/ sqrt( (x-1)**2 + (y-1)**2 + (z-1)**2 )
rhs = LinearForm (m*v.Trace()*ds(bonus_intorder=3)).Assemble()
with TaskManager(pajetrace=1000*1000*1000):
V = LaplaceSL(u*ds)*v*ds
Solve the linear system:
j = GridFunction(fesL2)
pre = BilinearForm(u*v*ds, diagonal=True).Assemble().mat.Inverse()
with TaskManager(pajetrace=1000*1000*1000):
CG(mat = V.mat, pre=pre, rhs = rhs.vec, sol=j.vec, tol=1e-8, maxsteps=200, initialize=False, printrates=True)
Draw (j);
CG iteration 1, residual = 2.185632470081333
CG iteration 2, residual = 0.5511118070234002
CG iteration 3, residual = 0.1311310259046071
CG iteration 4, residual = 0.031078990634675403
CG iteration 5, residual = 0.007370161304676199
CG iteration 6, residual = 0.0017872719313664826
CG iteration 7, residual = 0.0005164640897886519
CG iteration 8, residual = 0.0002492780566936905
CG iteration 9, residual = 0.00027505280100685716
CG iteration 10, residual = 0.0001804296883779487
CG iteration 11, residual = 0.00013054631855996055
CG iteration 12, residual = 3.7227312416526054e-05
CG iteration 13, residual = 3.312346253569015e-05
CG iteration 14, residual = 1.610364811063763e-05
CG iteration 15, residual = 9.915860637612635e-06
CG iteration 16, residual = 1.0658417152027922e-05
CG iteration 17, residual = 7.466789251299928e-06
CG iteration 18, residual = 7.402407545278815e-06
CG iteration 19, residual = 5.4726515089507445e-06
CG iteration 20, residual = 2.3569221270401377e-06
CG iteration 21, residual = 1.647571884000155e-06
CG iteration 22, residual = 1.713550652759644e-06
CG iteration 23, residual = 1.3120434766960407e-06
CG iteration 24, residual = 6.358196555359483e-07
CG iteration 25, residual = 1.1080271990215965e-06
CG iteration 26, residual = 2.6228375487977723e-07
CG iteration 27, residual = 2.3839343618324335e-07
CG iteration 28, residual = 2.521414429331238e-07
CG iteration 29, residual = 1.3798656192496498e-07
CG iteration 30, residual = 1.3285753304935006e-07
CG iteration 31, residual = 7.050800576568768e-08
CG iteration 32, residual = 1.8106090955115502e-07
CG iteration 33, residual = 5.2934875936904487e-08
CG iteration 34, residual = 3.767213790499984e-08
CG iteration 35, residual = 3.122043118455898e-08
CG iteration 36, residual = 2.9167854465250435e-08
CG iteration 37, residual = 1.3858160148081166e-08
type(V)
#for t in Timers():
# if "ngbem" in t["name"]:
# print (t)
ngsolve.bem.IntegralOperator
screen = WorkPlane(Axes( (0,0,0), Z, X)).RectangleC(0.5,0.5).Face()
screen.faces.name="screen"
vismesh = screen.GenerateMesh(maxh=0.05)
#Draw (vismesh);
SLPotential = LaplaceSL( u*ds)
repformula = SLPotential(j)
fes_screen = H1(vismesh, order=5)
gf_screen = GridFunction(fes_screen)
with TaskManager():
gf_screen.Set(repformula, definedon=vismesh.Boundaries("screen"))
Draw(repformula,vismesh)
BaseWebGuiScene
References
For details on the analysis of boundary integral equations derived from elliptic partial differential equations, see for instance Strongly Elliptic Systems and Boundary Integral Equations.
The integration of singular pairings is done as proposed in Randelementmethoden
The adaptive cross approximation is done as proposed in Hierarchical Matrices.