Solve a partial differential equation
With all the previously notions we approach, the definition of a partial differential equation and boundary conditions are our next step. More details on these aspects can be retrieve at this page.
1. Variational formulation
This example refers to a laplacian problem, define by
After turning the Strong formulation into its weak form, we have
where \(u\) is the unknown and \(v\) a test function. The left side is known as the bilinear form \(a\) and the right side is the linear form \(l\).
2. Implementation
The steps to implement this problem are
-
Loading a 2D mesh, creating the function space \(V_h\), composed of piecewise polynomial functions of order 2, and its associated elements
auto mesh = loadMesh(_mesh=new Mesh<Simplex<2>>);
auto Vh = Pch<2>( mesh );
auto u = Vh->element();
auto v = Vh->element();
-
Define the linear form \(l\) with test function space \(V_h\)
auto l = form1( _test=Vh );
l = integrate(_range=elements(mesh),
_expr=id(v));
-
Define the bilinear form \(a\) with \(V_h\) as test and trial function spaces
auto a = form2( _trial=Vh, _test=Vh);
a = integrate(_range=elements(mesh),
_expr=gradt(u)*trans(grad(v)) );
form1
and form2
are used to define respectively the left and right
side of our partial differential equation.
-
Add Dirichlet boundary condition on u
a+=on(_range=boundaryfaces(mesh),
_rhs=l, _element=u, _expr=cst(0.) );
We impose, in this case, \(u=0\) on \(\partial\Omega\), with the keyword on
.
-
Solving the problem
a.solve(_rhs=l,_solution=u);
-
Exporting the solution
auto e = exporter( _mesh=mesh );
e->add( "u", u );
e->save();
The complete code reads as follows :
#include <feel/feel.hpp>
int main(int argc, char**argv )
{
using namespace Feel;
Environment env( _argc=argc, _argv=argv,
_about=about(_name="qs_laplacian",
_author="Feel++ Consortium",
_email="feelpp-devel@feelpp.org"));
auto mesh = loadMesh(_mesh=new Mesh<Simplex<2>>);
auto Vh = Pch<2>( mesh );
auto u = Vh->element();
auto v = Vh->element();
auto l = form1( _test=Vh );
l = integrate(_range=elements(mesh),
_expr=id(v));
auto a = form2( _trial=Vh, _test=Vh);
a = integrate(_range=elements(mesh),
_expr=gradt(u)*trans(grad(v)) );
a+=on(_range=boundaryfaces(mesh), _rhs=l, _element=u, _expr=cst(0.) );
a.solve(_rhs=l,_solution=u);
auto e = exporter( _mesh=mesh );
e->add( "u", u );
e->save();
}
and the corresponding config file
[gmsh]
hsize=1e-1