1. Spaces and elements

You’ve learned how to discretize the space you want to compute on. You now have to learn how to define and use function spaces and elements of functions spaces. For advanced informations on this subject, you can look in the Function Space documentation.

1.1. Constructing a function space

  • Loading a Mesh in 2D

auto mesh = loadMesh(_mesh=new Mesh<Simplex<2>>);
  • For basic function spaces, we have predetermined constructors:

auto Xh = Pch<2>( mesh );
  • Defining an element

auto u = Xh->element( "u" );
auto w = Xh->element( "w" );

One can also use :

  • Pdh<ORDER>(mesh) : Polynomial Discontinuous

  • Pvh<ORDER>(mesh) : Polynomial Continuous Vectorial

  • Pdhv<ORDER>(mesh) : Polynomial Discontinuous Vectorial

  • Pchm<ORDER>(mesh) : Polynomial Continuous Matrix

  • Dh<ORDER>(mesh) : RaviartThomas function space

  • Ned1h<ORDER>(mesh) : Nedelec function spaces

1.2. Implementation

The implementation reads are follows

#include <feel/feelcore/environment.hpp>
#include <feel/feeldiscr/pch.hpp>
#include <feel/feelfilters/loadmesh.hpp>
#include <feel/feelfilters/exporter.hpp>
#include <feel/feelvf/vf.hpp>

using namespace Feel;

int main( int argc, char** argv )
{

    //Initialize Feel++ Environment
    Environment env( _argc=argc, _argv=argv,
                     _about=about( _name="myfunctionspace",
                                   _author="Feel++ Consortium",
                                   _email="feelpp-devel@feelpp.org" )  );

    // create the mesh
    auto mesh = loadMesh(_mesh=new Mesh<Simplex<2>>);

    // function space \( X_h \) using order 2 Lagrange basis functions
    auto Xh = Pch<2>( mesh );

    auto g = expr<4>( soption(_name="functions.g"));
    auto gradg = grad<3>(g);

    // elements of \( u,w \in X_h \)
    auto u = Xh->element( "u" );
    auto w = Xh->element( "w" );

		// build the interpolant of u
    u.on( _range=elements( mesh ), _expr=g );

		// build the interpolant of the interpolation error
    w.on( _range=elements( mesh ), _expr=idv( u )-g );

    // compute L2 norms \(||\cdot||_{L^2}\)
    double L2g = normL2( elements( mesh ), g );
    double H1g = normL2( elements( mesh ), _expr=g,_grad_expr=gradg );
    double L2uerror = normL2( elements( mesh ), ( idv( u )-g ) );
    double H1uerror = normH1( elements( mesh ), _expr=( idv( u )-g ),
                              _grad_expr=( gradv( u )-gradg ) );
    
    Feel::cout << "||u-g||_0 = " << L2uerror/L2g << std::endl;
    Feel::cout << "||u-g||_1 = " << H1uerror/H1g << std::endl;

    // export for post-processing
    auto e = exporter( _mesh=mesh );

	 	// save interpolant
    e->add( "g", u );

	 	// save interpolant of interpolation error
    e->add( "u-g", w );

    e->save();

}

and the associated config file

[gmsh]
# default is hypercube
shape=hypercube
# you can try ellipsoid
#shape=ellipsoid

[functions]
g=x*y*(y*2.2+4.3)*(2.1*x-1.3):x:y