Dirichlet Laplace Indirect Method#
keys: homogeneous Dirichlet bvp, single layer potential, ACA
from netgen.occ import *
from ngsolve import *
from ngsolve.webgui import Draw
from ngbem import *
from ngsolve import Projector, Preconditioner
from ngsolve.krylovspace import CG
Loading ngbem library
We consider the Dirichlet boundary value problem
Let us choose the following ansatz for the solution \(u\in H^1(\Omega)\) (indirect ansatz)
and solve for the density \(j\in H^{-\frac12}(\Gamma)\) by the boundary element method, i.e. the numerical solution of the variational formulation
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()
Define Dirichlet data \(u_0\) and compute the right hand side vector:
u0 = 1/ sqrt( (x-1)**2 + (y-1)**2 + (z-1)**2 )
rhs = LinearForm (u0*v.Trace()*ds(bonus_intorder=3)).Assemble()
The discretisation of the above variational formulation leads to a system of linear equations, ie
where \(\mathrm{V}\) is the single layer potential operator. \(\mathrm V\) is regular and symmetric.
Demo 1: Assemble the single layer operator \(V\) as dense matrix and solve for unknwon density \(j\):
j = GridFunction(fesL2)
pre = BilinearForm(u*v*ds, diagonal=True).Assemble().mat.Inverse()
with TaskManager(pajetrace=1000*1000*1000):
V = SingleLayerPotentialOperator(fesL2, intorder=10, method="dense")
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.185628444636173
CG iteration 2, residual = 0.5511126197504223
CG iteration 3, residual = 0.1311312543903476
CG iteration 4, residual = 0.031075382341886653
CG iteration 5, residual = 0.007368321718552715
CG iteration 6, residual = 0.0017873102488004224
CG iteration 7, residual = 0.0005185169856633695
CG iteration 8, residual = 0.00025605265661500233
CG iteration 9, residual = 0.0003206576934490297
CG iteration 10, residual = 0.00011035885851815262
CG iteration 11, residual = 0.00016752392864684382
CG iteration 12, residual = 4.08958140444724e-05
CG iteration 13, residual = 3.274472821469365e-05
CG iteration 14, residual = 1.632572462927271e-05
CG iteration 15, residual = 1.0240009168263005e-05
CG iteration 16, residual = 9.235240212462255e-06
CG iteration 17, residual = 7.881910845196794e-06
CG iteration 18, residual = 4.84151330511191e-06
CG iteration 19, residual = 3.082553945086529e-06
CG iteration 20, residual = 3.862950278127602e-06
CG iteration 21, residual = 1.8320936585767728e-06
CG iteration 22, residual = 1.8105355171682958e-06
CG iteration 23, residual = 1.4120630469467857e-06
CG iteration 24, residual = 5.770021991178657e-07
CG iteration 25, residual = 2.9626965296568e-07
CG iteration 26, residual = 2.5728166005001245e-07
CG iteration 27, residual = 4.359698034344633e-07
CG iteration 28, residual = 1.7797189551278336e-07
CG iteration 29, residual = 1.7317514759169652e-07
CG iteration 30, residual = 1.7259325500745118e-07
CG iteration 31, residual = 7.969862678472237e-08
CG iteration 32, residual = 7.935418621481961e-08
CG iteration 33, residual = 3.85136669005619e-08
CG iteration 34, residual = 2.8360883014874435e-08
CG iteration 35, residual = 1.6221553170952995e-08
Demo 2: Approximate the single layer operator \(V\) by ACA. There are three parameters that define the approximation:
leafsize
is the minimal size of a cluster in the cluster treeeta
relates to the so-called admissibility condition and determines the type of block: either near or far-fieldeps
is the accuracy of low rank approximation of a far field block
pre = BilinearForm(u*v*ds, diagonal=True).Assemble().mat.Inverse()
with TaskManager(pajetrace=1000*1000*1000):
V = SingleLayerPotentialOperator(fesL2, intorder=10, leafsize=40, eta=3., eps=1e-4, method="aca", testhmatrix=True)
CG(mat = V.mat, pre=pre, rhs = rhs.vec, sol=j.vec, tol=1e-8, maxsteps=200, initialize=False, printrates=True)
Draw (j);
dense: 3080 x 3080
compression rate 0.349931 2-norm error 0.000589323
CG iteration 1, residual = 0.00010372613791385414
CG iteration 2, residual = 0.00011332303929202542
CG iteration 3, residual = 4.8475130043928946e-05
CG iteration 4, residual = 3.752744414069605e-05
CG iteration 5, residual = 2.5063257847685102e-05
CG iteration 6, residual = 2.201161658598163e-05
CG iteration 7, residual = 4.0910741896836506e-05
CG iteration 8, residual = 1.5722470629475495e-05
CG iteration 9, residual = 1.1398173534547079e-05
CG iteration 10, residual = 8.601114677452872e-06
CG iteration 11, residual = 1.7985157762401756e-05
CG iteration 12, residual = 6.24956732982615e-06
CG iteration 13, residual = 6.840010024435814e-06
CG iteration 14, residual = 3.1039996622566697e-06
CG iteration 15, residual = 2.601687250773817e-06
CG iteration 16, residual = 3.3905259452258448e-06
CG iteration 17, residual = 2.3772167442172267e-06
CG iteration 18, residual = 1.2484134584125856e-06
CG iteration 19, residual = 1.0020809034945668e-06
CG iteration 20, residual = 1.4679545198086889e-06
CG iteration 21, residual = 1.345029797669753e-06
CG iteration 22, residual = 6.233413646170433e-07
CG iteration 23, residual = 5.316529772220773e-07
CG iteration 24, residual = 3.8221074414510546e-07
CG iteration 25, residual = 4.2254716868647137e-07
CG iteration 26, residual = 1.9054567735665295e-07
CG iteration 27, residual = 2.456064134128932e-07
CG iteration 28, residual = 1.8998524316205275e-07
CG iteration 29, residual = 2.173992286349492e-07
CG iteration 30, residual = 1.2534619876156766e-07
CG iteration 31, residual = 8.403493254757788e-08
CG iteration 32, residual = 4.3332209270053146e-08
CG iteration 33, residual = 1.0157994209403936e-07
CG iteration 34, residual = 2.9761572643430306e-08
CG iteration 35, residual = 4.0323202672285155e-08
CG iteration 36, residual = 2.737427871216972e-08
CG iteration 37, residual = 1.7371828631137093e-08
CG iteration 38, residual = 3.452055776446457e-08
CG iteration 39, residual = 1.3309568079797635e-08
CG iteration 40, residual = 9.486019205138243e-09
CG iteration 41, residual = 6.427829807220539e-09
CG iteration 42, residual = 1.2848413223273628e-08
CG iteration 43, residual = 3.761031417102926e-09
CG iteration 44, residual = 4.679452921229483e-09
CG iteration 45, residual = 2.190122037970437e-09
CG iteration 46, residual = 1.996239646971565e-09
CG iteration 47, residual = 2.3159899902351333e-09
CG iteration 48, residual = 1.2723913819350062e-09
CG iteration 49, residual = 9.31259051689337e-10
CG iteration 50, residual = 1.1204428304854894e-09
CG iteration 51, residual = 1.413388424930364e-09
CG iteration 52, residual = 8.997634695803242e-10
CG iteration 53, residual = 4.4531603486308826e-10
CG iteration 54, residual = 4.5270100016281045e-10
CG iteration 55, residual = 2.6152775675607896e-10
CG iteration 56, residual = 4.617915988555627e-10
CG iteration 57, residual = 1.5886672961052302e-10
CG iteration 58, residual = 2.7846309529962185e-10
CG iteration 59, residual = 8.723015476489554e-11
CG iteration 60, residual = 2.5907217972154056e-10
CG iteration 61, residual = 7.938117887022281e-11
CG iteration 62, residual = 6.271285664807571e-11
CG iteration 63, residual = 4.6670339271953476e-11
CG iteration 64, residual = 5.1924137459351305e-11
CG iteration 65, residual = 4.366007100324626e-11
CG iteration 66, residual = 4.353862381900156e-11
CG iteration 67, residual = 2.195362901022156e-11
CG iteration 68, residual = 1.762485504806998e-11
CG iteration 69, residual = 2.4145021673366737e-11
CG iteration 70, residual = 9.719501974076612e-12
CG iteration 71, residual = 9.661870415501173e-12
CG iteration 72, residual = 1.0814296376953874e-11
CG iteration 73, residual = 4.518647797308727e-12
CG iteration 74, residual = 1.2093135661526256e-11
CG iteration 75, residual = 5.420444183339184e-12
CG iteration 76, residual = 2.952789092939208e-12
CG iteration 77, residual = 1.7325571207483807e-12
CG iteration 78, residual = 3.850113041607153e-12
CG iteration 79, residual = 2.0103340936785782e-12
CG iteration 80, residual = 1.8670382142067295e-12
CG iteration 81, residual = 1.0746221727153705e-12
CG iteration 82, residual = 7.385642929343038e-13
for t in Timers():
if "ngbem" in t["name"]:
print (t)
{'name': 'ngbem FarFieldBlock - matvec2 LaplaceSL', 'time': 0.0076680862051428525, 'counts': 1831, 'flops': 12485592.0, 'Gflop/s': 1.6282539953223438}
{'name': 'ngbem FarFieldBlock - matvec1 LaplaceSL', 'time': 0.0016000993157137982, 'counts': 1831, 'flops': 12462408.0, 'Gflop/s': 7.788521548389369}
{'name': 'ngbem FarFieldBlock - norm LaplaceSL', 'time': 0.02413285989228843, 'counts': 1831, 'flops': 0.0, 'Gflop/s': 0.0}
{'name': 'ngbem FarFieldBlock - kernel LaplaceSL', 'time': 0.005464391943065623, 'counts': 3662, 'flops': 5036040.0, 'Gflop/s': 0.9216103186724726}
{'name': 'ngbem FarFieldBlock - ACA LaplaceSL', 'time': 0.06518542551288707, 'counts': 174, 'flops': 0.0, 'Gflop/s': 0.0}
{'name': 'ngbem FarFieldBlock LaplaceSL', 'time': 0.12686599146346794, 'counts': 189, 'flops': 0.0, 'Gflop/s': 0.0}
{'name': 'ngbem - HMatrix::MultAdd', 'time': 0.1696692086510814, 'counts': 147, 'flops': 0.0, 'Gflop/s': 0.0}
{'name': 'ngbem disjoint LaplaceSL', 'time': 1.6634663368779543, 'counts': 94631, 'flops': 0.0, 'Gflop/s': 0.0}
{'name': 'ngbem common edge LaplaceSL', 'time': 1.69745426576888, 'counts': 1146, 'flops': 0.0, 'Gflop/s': 0.0}
{'name': 'ngbem common vertex LaplaceSL', 'time': 2.00345731113448, 'counts': 3371, 'flops': 0.0, 'Gflop/s': 0.0}
{'name': 'ngbem identic panel LaplaceSL', 'time': 0.6705158937567653, 'counts': 382, 'flops': 0.0, 'Gflop/s': 0.0}
{'name': 'ngbem - loops LaplaceSL', 'time': 6.10330901470501, 'counts': 299, 'flops': 0.0, 'Gflop/s': 0.0}
{'name': 'ngbem - all LaplaceSL', 'time': 6.274055100880135, 'counts': 299, 'flops': 0.0, 'Gflop/s': 0.0}
{'name': 'ngbem - BaseClass::CalcHMatrix', 'time': 2.826205817393841, 'counts': 2, 'flops': 0.0, 'Gflop/s': 0.0}
Notes:
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.