Nodal Projection
An important keyword is project
which allows to compute the interpolant of an expression with respect to a nodal function space over a part of the mesh or the whole mesh. The interface is as follows
project( _space=<nodal function space in which the interpolant lives>
_range=<domain range iterators>,
_expr=<expression to be interpolated>, .... )
Here are some examples:
typedef FunctionSpace<Mesh<Simplex<$d$>,
bases<Lagrange<1,Vectorial> > > Xhv_type;
auto Xhv = Xhv_type::New( mesh );
auto coord = project( _space=Xhv, _range=elements(mesh), _expr=P() );
auto dx_coord = project( _space=Xhv, _range=elements(mesh), _expr=dxv(coord) );
auto dy_coord = project( _space=Xhv, _range=elements(mesh), _expr=dyv(coord) );
Projection Operator
A projection operator is available that supports:
- \(L_2\) projection
- \(H_1\) projection
Project Specific Expressions
You may want to customise the projected expression, that is to define your own expression. We have based that mechanism over the GiNaC librarie or the Functor.
The idea with GiNaC is to provide a string which will be parsed to generate a function:
po::options_description opts ( "myOptions ");
opts.add_options()
( "_ex_", po::value<std::string>()->default_value( "cos(x)*sin(y)" ), "my Expression to project" );
using namespace Feel;
Environment env( _argc=argc, _argv=argv,
_desc=opts,
_about=about(_name="myexpression",
_author="Feel++ Consortium",
_email="feelpp-devel@feelpp.org"));
const int Dim = 2;
auto mesh = unitSquare();
auto e = exporter( _mesh=mesh );
auto Vh = Pch<1>( mesh );
auto u = Vh->element();
auto v = Vh->element();
std::vector<GiNaC::symbol> vars = symbols<Dim>();
std::string _u = option(_name="_ex_").as<std::string>();
GiNaC::ex expr_u = parse(_u,vars);
u = vf::project( _space=Vh, _range=elements(mesh), _expr=expr(expr_u,vars) );
To use the Functor, you have to define in the Feel namespace a struct with some variable. That struct will provide an operator()
interface with specific signature.
namespace Feel
{
struct myFunctor
{
static const size_type context = vm::JACOBIAN|vm::POINT;
typedef double value_type;
typedef Feel::uint16_type uint16_type;
static const uint16_type rank = 0;
static const uint16_type imorder = 1;
static const bool imIsPoly = true;
double operator()( uint16_type, uint16_type, ublas::vector<double> const& x, ublas::vector<double> const& ) const
{
double a = x[0];
double b = x[1];
return _esp*std::min(a,b);
}
void setEps(double _a=0.){ _esp = _a;}
double _esp;
};
}
and then, you are allowed to define a functor based expression on that way:
Feel::myFunctor _f;
_f.setEps(0.1);
v = vf::project( _space=Vh, _range=elements(mesh), _expr=idf(_f));
top