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 save the output of each function on each mesh to XDMF:

  XDMFFile("v1.xdmf").write(v1);
  XDMFFile("v3.xdmf").write(v3);

  return 0;
}