Dear All,

I’ve been also curious about the L2 projection operator from the fine to the coarse levels - I guess , this is what is meant in the topic title). I’ve been testing an implementation of it a little (see other recent posts of mine) and found that MinRes, for example, throws an error when the prolongation matrix is computed between L2 spaces:

netgen.libngpy._meshing.NgException: Prolongation::GetNDofLevel not overloaded

This behaviour doesn’t manifest for prolongations between H1 spaces. I attach the file where the only thing that happens is the multiplication of a course vector with something that involves prolongation matrix. In fact, it should be the coarse mass matrix computed from the fine level mass matrix. Any help is appreciated!

from netgen.csg import CSGeometry, OrthoBrick, Pnt

from ngsolve import *

#
Geometry

cube = CSGeometry()

cube.Add(OrthoBrick(Pnt(-2.0, -2.0, -2.0), Pnt(2.0, 2.0, 2.0)))

#
Mesh sizes

N=4

maxh = 4.0/N #to be refined later

maxH = 4.0/N

#Mesh generation

mesh = Mesh(cube.GenerateMesh(maxh=maxh, quad_dominated=False))

mesh_c = Mesh(cube.GenerateMesh(maxh=maxH, quad_dominated=False))

#forcing

pi=3.141592

coef=CoefficientFunction(((3 * pi * pi + 1)*sin(pi * x)*sin(pi * y)*sin(pi * z)))

#FE Spaces

#changing all the L2 spaces to H1 resolves the bug

Vh = L2(mesh, order=1) #fine level space

u, v = Vh.TnT()

Rh = L2(mesh_c, order=1)#coarse level space

Rh_avatar= L2(mesh, order=1)#used only to compute prolongation operator from coarse to fine

#Mesh refinement from level=0 to level=1

mesh.ngmesh.Refine()

Vh.Update()

Rh_avatar.Update() #Rh remains to be coarse of level=0

#
Bilinear forms:

mass = BilinearForm(Vh, symmetric=True) #fine level mass matrix M_h

mass += (u * v) * dx

mass.Assemble()

#Grid function

gfz=GridFunction(Rh)

gfz.Set(coef);

#
Prolongation operator from mesh-level 0 to level 1:

prol = Rh_avatar.Prolongation().Operator(1)

coarse_to_fine_to_coarse_mass = prol.T @ mass.mat @ prol#=coarse mass matrix

#computing coarse mass_matrix * coarse vector

diff = gfz.vec.CreateVector()

diff += coarse_to_fine_to_coarse_mass * gfz.vec

#!!!error: netgen.libngpy._meshing.NgException: Prolongation::GetNDofLevel not overloaded

exit(0);