L2 GridFunction and Integration order


I have two questions. It would be very helpful if anyone can answer any of them. Thank you.

  1. I have a mesh with two materials (“inner” and “outer” ) and I have an L2 GridFunction defined on the inner material. I’d like to define an L2 Facet GridFunction on the outer material and then set the values on the interface (“interior boundary”) based on the L2 GridFunction.

I tried the following code but it doesn’t work. The dofs of the L2 Facet GridFunction are still all zeros. I wonder what’s the right way to do this.

fes0 = L2(mesh, order = 1, definedon = mesh.Materials("inner"))
gf0 = GridFunction(fes0)
# define gf0 in some way, for example gf0.Set(x**2+y**2)

fes1 = FacetFESpace(mesh, order = 1, definedon = mesh.Materials("outer"))
gf1 = GridFunction(fes1)
gf1.Set(gf0, definedon = mesh.Boundaries("interior bc"))

print( gf1.vec). # it's still all 0s
  1. Another question I have is how I can set order when I integrate with dx, ds. I tried the following but it gives me an error.
Integrate(u*v*dx(element_boundary=True), mesh, order=5)



Hi Oliver,

here you can use the BoundaryFromVolumeCF, an example is attached.

copied from help(BoundaryFromVolumeCF):

BoundaryFromVolumeCF(…) method of builtins.PyCapsule instance
BoundaryFromVolumeCF(vol_cf: ngsolve.fem.CoefficientFunction) → ngsolve.fem.CoefficientFunction

Allows the evaluation of volumetric functions on the boundary.

When evaluated on a boundary element, this function searches for the associated
volume element, transforms the local coordinates, and evaluates the function in the
volume. A typical use case is to visualize L2-functions, or mechanical stresses at
the boundary.

It is different from the boundary Trace()-operator. The trace provides a function
which is defined by boundary degrees of freedom only. E.g. the trace of an H(div)
function is only the normal component, while the BoundaryFromVolumeCF gives the
whole function. Obviously, the Trace() function is cheaper to evaluate.

If called on an interface, it evaluates from one side (which one is not specified).
If the function is only defined on one side, this side will be taken. One can use
a domain-wise CF to define a function only locally:
uloc = CoefficientFunction( [None, None, u, None] )

There are two possibilities to set the integration rules with dx - integrals:


… increase the default order by 3

provide a user-defined integration-rule for each element shape:

dx(intrules = { TRIG : IntegrationRule( [(x1,y1),(x2,y2), ..], [w1,w2,...]) })   

but, unfortunately, these settings are used only for assembling, and non of them is used in the Integrate ( func*dx ) function. It just uses fixed order=5.
I just added to use the bonus_intorder quite now, will be available tonight.


Attachment: l2boundary_2020-09-22.py

Hi Joachim,

Thank you for your reply. Everything works for me now.