Don't understand GetParentElement

More
2 years 9 months ago #4049 by HaraldMonsuur
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)

The output I got was
Code:
18446744073709551615 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 arxiv.org/abs/2009.00154 . Do you have any tips on tackling such a problem? It is related to a multigrid method.
More
2 years 8 months ago #4052 by joachim
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:
Code:
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:

github.com/JSchoeberl/iFEM/tree/master/multigrid

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
Time to create page: 0.150 seconds