Interpolation from a non-matching mesh¶
This example demonstrates how to interpolate functions between finite element spaces on non-matching meshes.
Note
Interpolation on non-matching meshes is not presently support in parallel. See https://bitbucket.org/fenics-project/dolfin/issues/162.
Implementation¶
The implementation is split in three files: two UFL form files containing the definition of finite elements, and a C++ file containing the runtime code.
Running this demo requires the files: main.cpp
,
P1.ufl
, P3.ufl
and CMakeLists.txt
.
UFL form file¶
The UFL files are implemented in P1.ufl
and
P1.ufl
, and the explanations of the UFL files can be found
at here (P1) and here (P3).
At the top we include the DOLFIN header file and the generated header files “P1.h” and “P2.h”. For convenience we also include the DOLFIN namespace.
#include <dolfin.h>
#include "P1.h"
#include "P3.h"
using namespace dolfin;
We then define an Expression
:
class MyExpression : public Expression
{
public:
void eval(Array<double>& values, const Array<double>& x) const
{
values[0] = sin(10.0*x[0])*sin(10.0*x[1]);
}
};
Next, the main
function is started and we create two unit square
meshes with a differing number of vertices in each direction:
int main()
{
// Create meshes
auto mesh0 = std::make_shared<UnitSquareMesh>(16, 16);
auto mesh1 = std::make_shared<UnitSquareMesh>(64, 64);
We create a linear Lagrange finite element space on the coarser mesh, and a cubic Lagrange space on the finer mesh:
// Create function spaces
auto P1 = std::make_shared<P1::FunctionSpace>(mesh0);
auto P3 = std::make_shared<P3::FunctionSpace>(mesh1);
One each space we create a finite element function:
// Create functions
Function v1(P1);
Function v3(P3);
We create an instantiation of MyExpression
, and interpolate it
into P3
:
// Interpolate expression into P3
MyExpression e;
v3.interpolate(e);
Now, we interpolate v3
into the linear finite element space on a
coarser grid:
v1.interpolate(v3);
Finally, we can visualise the function on the two meshes:
plot(v3);
plot(v1);
interactive();
return 0;
}