I want to integrate a CoefficientFunction over the boundary of a subdomain of the mesh. The subdomain is defined as a material.
Integrate(cf, mesh, BND, definedon = mesh.Materials(“mat1”))
integrate over the boundary of mat1?
Also I want to create a CoefficientFunction for the normal vector on the boundary of the subdomain. Is there any function that does that? specialcf.normal doesn’t seem to be able to do that.
We have now a very new BoundaryFromVolumeCF, which does what you need. Copy from the doc-string:
Help on built-in function BoundaryFromVolumeCF in module ngsolve.comp:
BoundaryFromVolumeCF(...) method of builtins.PyCapsule instance
BoundaryFromVolumeCF(vol_cf: ngsolve.fem.CoefficientFunction) -> ngsolve.fem.CoefficientFunction
Allows the evaluation of volumentric 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
It is different to 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
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] )
Attached is also a small test-file providing the domain-wise outgoing normal-vector.
In your case, you have to integrate over a boundary-region, which you have to define via boundary condition labels.
Thanks for the reply.
I downloaded and installed the latest version of NGSolve but BoundaryFromVolumeCF does not exist in my build. How can I install it?
you need the latest nightly build
I now have a Version of NGSolve with the BoundaryFromVolumeCF function and tried to get the integral over a subdomain boundary to work. It seems like the normal vector CoefficienFunction is zero everywhere. Also the doc is not very helpful. Can you better explain what that function does? Can you add the integral of gfu times the normals vetor over the inner domain boundary in the test file you provided?
That would probably help alot.
As usual, you integrate like that
print ("Integral = ", Integrate(bfv*bfv2, mesh, definedon=mesh.Boundaries("innerbnd")))
(whole example is attached).
the result is:
Integral = -0.108
see also my reply in
Thank you for the example. I now understand better what the BoundaryFromVolumeCoefficientFunction does.
I want to integrate the vector product of a vector field and the normal vectors over the domain boundary. Doing that I get strange results.
During some trial and error I found out that the result changes a lot when changing the finite element space of the GridFunction you give BoundaryFromVolumeCF. I made a small example file demonstrating that. By my understanding the Integral result should be the same, but I get:
CF Integral = -2.081668171172171e-17
H-Vec Integral = 7.816576618000729
H-Curl Integral = -2.0173882950217807
H-Div Integral = -0.20501329559045756
I mainly work with complex HCurl finite element spaces and in my application the result is nan, witch a vector product can not cause.
Can you clarify these results for me?
Thanks in advance.
don’t use -dim=3 with H(curl), H(div) or VectorH1, they are already vectorial. Otherwise, you create 3 copies of H(curL) …
fesVec = VectorH1(mesh, order=2) # , dim = 3)
fesCurl = HCurl(mesh, order=2) # , dim = 3)
fesDiv = HDiv(mesh, order=2) # , dim = 3)
Thank you for the clarification.
I still have a problem when using a CoefficientFunction that is the curl of a GridFunction (e.i. the solution of the fe-problem). I made a simple exaple file. When I run it I get the error
print("curl Integral = ", Integrate(Norm(bfcurl*bfv_normals), mesh, definedon=mesh.Boundaries(“innerbnd”)))
NgException: BaseVector::GetIndirect called
which is not very helpful. Do you have a solution to that?