How to interpolate between non-matching meshes in parallel?

You may be able to use PETScDMCollection from DOLFIN for this, without FEniCSTools. See the following modification of your example:

from dolfin import *

#from mshr import *
#from fenicstools import *
def transfer_function(fromFunc,toFunc):
    fromFunc.set_allow_extrapolation(True)
    A = PETScDMCollection.create_transfer_matrix\
        (fromFunc.ufl_function_space(),
         toFunc.ufl_function_space())
    toFunc.vector()[:] = A*fromFunc.vector()

mesh1 = UnitSquareMesh(16, 16)
V1 = FunctionSpace(mesh1, 'CG', 2)
u1 = interpolate(Expression("sin(pi*x[0])*cos(pi*x[1])", degree = 1), V1)
# Create a new _different_ mesh and FunctionSpace
mesh2 = UnitSquareMesh(10, 10)
x = mesh2.coordinates()
x[:, :] = x[:, :] * 0.5 + 0.25
V2 = FunctionSpace(mesh2, 'CG', 1)

#interpolate_nonmatching_mesh(u1, V2)
u2 = Function(V2)
transfer_function(u1,u2)

from matplotlib import pyplot as plt
plot(u1)
plt.show()
plot(u2)
plt.show()

(Depending on what you are doing, it may make sense to pre-compute and store the matrix A that is created in transfer_function instead of regenerating it with each call to transfer_function.)

3 Likes