Feel++ 0.91.0
|
typedef
//# marker1 # typedef FunctionSpace<mesh_type, bases<Lagrange<0,Scalar, Discontinuous> > > p0_space_type; typedef typename p0_space_type::element_type p0_element_type; //# endmarker1 #
P0 FunctionSpace typedef
//# marker2 # typedef bases<Lagrange<Order,Scalar,Continuous> > basis_type; typedef FunctionSpace<mesh_type, basis_type> space_type; typedef boost::shared_ptr<space_type> space_ptrtype; typedef typename space_type::element_type element_type; //# endmarker2 #
Now we turn to the instantiation of the function space of type
functionspace_type
. We have already instantiated a mesh
(see this Section) of type mesh_ptrtype
. The code looks like this
//# marker31 # mesh_ptrtype mesh = createGMSHMesh( _mesh=new mesh_type, _update=MESH_CHECK|MESH_UPDATE_FACES|MESH_UPDATE_EDGES|MESH_RENUMBER, _desc=domain( _name= (boost::format( "%1%-%2%-%3%" ) % shape % Dim % Order).str() , _shape=shape, _dim=Dim, _order=Order, _h=X[0] ) ); //# endmarker31 #
Then we instantiate using
space_type::New()
static member function and obtain a functionspace_ptrtype
.
space_ptrtype Xh = space_type::New( mesh );
We are now able to instantiate elements of the FunctionSpace
. Two ways are presented, one with the
auto
keyword allowing to infer automatically the type of elements
auto u = Xh->element( "u" );
and one knowing the actual type of the element
element_type v( Xh, "v" );
"u"
and "v"
are the name we give to these elements of First, we define some mathematical expression/functions
They are implemented using the new auto C++ keyword to infer the type of expression automatically.
//# marker4 # auto g = sin(2*pi*Px())*cos(2*pi*Py())*cos(2*pi*Pz()); auto f = (1-Px()*Px())*(1-Py()*Py())*(1-Pz()*Pz())*pow(trans(vf::P())*vf::P(),(alpha/2.0)); //# endmarker4 #
Then we build the interpolant (Lagrange interpolant in this case since we chose Lagrange basis function), by calling the vf::project()
function which can be applied on all or parts of the mesh
thanks to the mesh iterators such as elements(mesh)
or markedelements(mesh,marker)
. The return object is the interpolant of the function in the space given as an argument to
vf::project()
.
//# marker5 # u = vf::project( Xh, elements(mesh), g ); v = vf::project( Xh, elements(mesh), f ); w = vf::project( Xh, elements(mesh), idv(u)-g ); //# endmarker5 #
It is easy to compute norms
//# marker6 # double L2g2 = integrate( elements(mesh), g*g ).evaluate()(0,0); double L2uerror2 = integrate( elements(mesh), (idv(u)-g)*(idv(u)-g) ).evaluate()(0,0); Log() << "||u-g||_0=" << math::sqrt( L2uerror2/L2g2 ) << "\n"; double L2f2 = integrate( elements(mesh), f*f ).evaluate()(0,0); double L2verror2 = integrate( elements(mesh), (idv(v)-f)*(idv(v)-f) ).evaluate()(0,0); Log() << "||v-f||_0=" << math::sqrt( L2verror2/L2f2 ) << "\n"; //# endmarker6 #
projection
//# marker7 # exporter = export_ptrtype( export_type::New( this->vm(), (boost::format( "%1%-%2%-%3%-%4%" ) % this->about().appName() % shape % Dim % Order).str() ) ); exporter->step(0)->setMesh( mesh ); exporter->step(0)->add( "g", u ); exporter->step(0)->add( "u-g", w ); exporter->step(0)->add( "f", v ); exporter->save(); //# endmarker7 #
We execute this example on a simplex domain an export to the Gmsh format:
feel_doc_myfunctionspace --shape="simplex"--nochdir --exporter-format=gmsh
the output log of the execution of this example gives
Here are the graphical outputs on the d-simplex, d=1,2,3:
![]()
f on the Line | ![]()
f on the Triangle | ![]()
f on the Tetrahedron |
![]()
g on the Line | ![]()
g on the Triangle | ![]()
g on the Tetrahedron |
We execute this example on a hypercube domain an export to the Gmsh format:
feel_doc_myfunctionspace --shape="hypercube"--nochdir --exporter-format=gmsh
the output log of the execution of this example gives
Here are the graphical outputs on the d-hypercube, d=1,2,3:
![]()
f plot on Line | ![]()
f plot on Unit Square | ![]()
f plot on Unit Cube |
![]()
g plot on Line | ![]()
g plot on Unit Square | ![]()
g plot on Unit Cube |