When figuring out how mesh.GetParentElement works I found some weird behaviour of this function on a simple example:
[code]from ngsolve import *
from netgen.geom2d import SplineGeometry
geo = SplineGeometry()
geo.AddRectangle( (0, 0), (1, 1),
bcs = (“bottom”, “right”, “top”, “left”))
mesh = Mesh(geo.GenerateMesh())
mesh.Refine()
for el in mesh.Elements(VOL):
print(mesh.GetParentElement(el).nr)[/code]
The output I got was18446744073709551615
18446744073709551615
0
1
0
1
2
3
This is weird because every element in the mesh resulting from the refinement should have a parent element. Is this intended? Also, the first mesh only has two elements but there are four different parents?
I am trying to build a H^-1/2,~ preconditioner for the boundary from [2009.00154] Multilevel decompositions and norms for negative order Sobolev spaces . Do you have any tips on tackling such a problem? It is related to a multigrid method.
Hi Harald,
the logic is as follows:
Let nc be the number of coarse grid elements.
Each one of the first nc fine grid elements is the first child of the coarse grid element with same index, so we don’t have to store the parent number.
One refinement level consists indeed of two levels of bisection.
In your example, the two coarse-grid elements are bisected to obtain 4 elements, this gives the (0, 1) as elements 2 and 3 of your output.
The second level produces the last 4 elements (with parent indices 0,1,2,3).
Here is an example showing how use the representation for a piecewise constant prolongation:
from ngsolve import *
from netgen.geom2d import SplineGeometry
from ngsolve.webgui import Draw
geo = SplineGeometry()
geo.AddRectangle( (0, 0), (1, 1),
bcs = ("bottom", "right", "top", "left"))
mesh = Mesh(geo.GenerateMesh(maxh=0.2))
fes = L2(mesh, order=0)
gfu = GridFunction(fes, nested=False) # nested=True does the prolongation for you
gfu.Set(x)
Draw(gfu)
oldne = mesh.GetNE(VOL)
oldvec = gfu.vec
mesh.Refine()
fes.Update()
gfu.Update()
gfu.vec[0:oldne] = oldvec
for i in range(oldne, mesh.GetNE(VOL)):
gfu.vec[i] = gfu.vec[mesh.GetParentElement(ElementId(VOL,i)).nr]
Draw (gfu);
For coding multigrid methods from Python you may have a look into:
You can obtain the prolongation operator from the finite element space, so you don’t have to worry about the details of the representation.
Joachim