1. Interpolation

Feel++ has a very powerful interpolation framework which allows to:

  • transfer functions from one mesh to another

  • transfer functions from one space type to another.

this is done seamlessly in parallel. The framework provides a set of C++ classes and C++ free-functions enabled short, concise and expressive handling of interpolation.

1.1. Using interpolation operator

Building interpolation operator Ih:P1c,hP0td.h
using MeshType = Mesh<Simplex<2>>;
auto mesh = loadMesh( _mesh=new MeshType );
auto P1h = Pch<1>( mesh );
auto P0h = Pdh<0>( mesh );
auto Ih = I( _domain=P1h, _image=P0h );
cpp

1.2. De Rahm Diagram

The De Rahm diagram reads as follows: the range of each of the operators coincides with the null space of the next operator in the sequence below, and the last map is a surjection.

H1(Ω)Hcurl(Ω)×Hdiv(Ω)L2(Ω)

An important result is that the diagram transfers to the discrete level

H1(Ω)Hcurl(Ω)×Hdiv(Ω)L2(Ω)πc,h πcurl,h πdiv,h πd,h UhVh×WhZh

The diagram above is commutative which means that we have the following properties:

(πc,hu)=πcurl,h(u),×(πcurl,hu)=πdiv,h(×u),(πdiv,hu)=πd,h(u)
The diagram can be restricted to functions satisfying the homogeneous Dirichlet boundary conditions
H10(Ω)Hcurl0(Ω)×Hdiv0(Ω)L20(Ω)

Interpolation operators are provided as is or as shared pointers. The table below presents the alternatives.

Table 1. Table of Interpolation operators

C++ object

C++ Type

C++ shared object

C++ Type

Mathematical operator

I(_domain=Xh,_image=Yh)

I_t<functionspace_type<decltype(Xh)>, functionspace_type<decltype(Xh)>>

IPtr(…​)

I_ptr_t<functionspace_type<decltype(Xh)>, functionspace_type<decltype(Xh)>>

I:XhYh

Grad(_domain=Xh,_image=Wh)

Grad_t<functionspace_type<decltype(Xh)>, functionspace_type<decltype(Wh)>>

GradPtr(…​)

Grad_ptr_t<functionspace_type<decltype(Xh)>, functionspace_type<decltype(Wh)>>

:XhWh

Curl(_domain=Wh,_image=Vh)

Curl_t<functionspace_type<decltype(Wh)>, functionspace_type<decltype(Vh)>>

CurlPtr(…​)

Curl_ptr_t<functionspace_type<decltype(Wh)>, functionspace_type<decltype(Vh)>>

×:WhVh

Div(_domain=Vh,_image=Zh)

Div_t<functionspace_type<decltype(Vh)>, functionspace_type<decltype(Zh)>>

DivPtr(…​)

Div_ptr_t<functionspace_type<decltype(Vh)>, functionspace_type<decltype(Zh)>>

:VhZh

Building the discrete operators associated to the De Rahm diagram in Feel++
auto mesh = loadMesh( _mesh=new Mesh<Simplex<Dim>>());
auto Xh = Pch<1>(mesh);
auto Gh = Ned1h<0>(mesh);
auto Ch = Dh<0>(mesh);
auto P0h = Pdh<0>(mesh);
auto Igrad = Grad( _domainSpace = Xh, _imageSpace=Gh );
auto Icurl = Curl( _domainSpace = Gh, _imageSpace=Ch );
auto Idiv = Div( _domainSpace = Ch, _imageSpace=P0h );

auto u = Xh->element(<expr>);
auto w = Igrad(u); // w in Gh
auto x = Icurl(w); // z in Ch
auto y = Idiv(x); // y in P0h
cpp