Info on Trace() operator for surface PDEs

Hi, and thanks a lot for the great work.

I was wondering if you could give me more information on what is actually performed when one takes the Trace() operator or grad().Trace()/Grad().Trace() as described in 6.1.2 Surface PDEs — NGS-Py 6.2.2305 documentation.

  • I am interested in both the scalar and especially the vector case. How does it deal with VectorH1 functions vs H1(dim=3) and their tangential gradients?
  • It is written “To be consistent, also here the Trace operator has to be used”, but I have tried to use for example Hdiv spaces on surfaces without the Trace() and it seems to work fine anyways, can it actually be omitted?
  • If I apply a deformation to the mesh, functions like specialcf.normal(dim) are updated accordingly, right? And are those functions what is used for computing Trace() in the case of H1,Hcurl etc?
  • Do you have any advice on how to correctly implement some new surface element starting from what is described in 9.1 Implementation of Finite Elements — NGS-Py 6.2.2305 documentation (which classes I should focus on implementing etc)?

Thanks a lot for any help!


Quite a lot of questions :slight_smile:

basically each space (and therefore the trial/testfunctions) have different evaluators, which “work together” with the mesh element to evaluate fem basis functions and or operators on them.
when doing grad(u) u basically ask the space for the Deriv operator (in H1 case). grad(u).Trace() asks for the boundary gradient operator (tangential trace of gradient). Each of these operators is implemented seperately.

Sometimes operators work for multiple settings (for example H1 evaluation, doesn’t matter if it gets the boundary element or volume element - same operator works) then you do not have to provide the Trace operator, but it doesn’t hurt and I think it is not really easy to see when you need it and when not if you do not know how the basis is implemented, so in general use Trace on boundaries.

grad(u).Trace() and grad(u.Trace()) return the same operator, so you can write it either way.

yes if you apply deformation to the mesh everything is evaluated on the deformed mesh, also normal,… But no, as said above, trace operators on each space are implemented as separate evaluators.

Depends what surface elements you want to implement, but yes, I think 9.1 is a good starting point for doing this. You can also look at the source code at implementation for example of L2Surface space in comp/l2hofespace.hpp /cpp . See there how evaluator / flux_evaluator are added to the space (these you will have to create / take from other spaces).


Yes, I apologize, I should have divided them.

So basically I have to go and see inside the single cpp files how the trace is implemented for every space.

Thanks for the information.


normally you should always use trace when evaluating on boundaries

Yes, absolutely, thanks!