Interpolating into a space of higher polynomial degree

Hello,

I have functions in a FE space (e.g. Lagrange) of polynomial degree k-1 and want to compute the representation of this function in the same FE space but of polynomial degree k (see example below). I could use the interpolate function, but since I have many functions, I want to use a matrix that maps the corresponding vector representation of the function in the space of polynomial degree k-1 to the vector representation of the function in the space of polynomial degree k. Is there a fast way to design such a matrix?

Best regards,
Johannes

from dolfin import *
k = 3
mesh = UnitSquareMesh(3,3)
Vk = FunctionSpace(mesh,‘P’,k)
Vkm1 = FunctionSpace(mesh,‘P’,k-1)
u_km1 = Function(Vkm1)
u_km1_array = u_km1.vector().get_local()
u_km1_array[0] = 4.0
u_km1.vector().set_local(u_km1_array) #some function in Vkm1
u_km = interpolate(u_km1, Vk)
print(assemble((u_km-u_km1)**2*dx))

instead: design a matrix M s.t. M*u_km1_array = u_km.vector().get_local()

Try using the PETScDMCollection functionality:

from dolfin import *

# Mesh and function spaces:
mesh = UnitSquareMesh(16, 16)
k = 3
V1 = FunctionSpace(mesh, 'CG', k-1)
V2 = FunctionSpace(mesh, 'CG', k)

# Create a nonzero function in space V1:
x = SpatialCoordinate(mesh)
u1 = project(dot(x,x),V1)

# Transfer it to a function in V2 using a transfer matrix, M:
u2 = Function(V2)
M = PETScDMCollection.create_transfer_matrix(V1,V2)
u2.vector()[:] = M*u1.vector()

# Check that the functions are the same (since V1 \subset V2):
e = u1-u2
print(sqrt(assemble(inner(e,e)*dx)))
2 Likes

Hi,

this works. Thanks a lot.

Best regard,

Johannes

Hi kamensky! Thanks for the suggestion. I am also trying to use it. In my case I have two function spaces. One is dealing with scalar value “T = FunctionSpace(mesh, “Lagrange”, 1)” while the other is “V = VectorFunctionSpace(meshComplete, “Lagrange”, 2)” dealing with vector value solution. I want to project my solution from T to V. Would it be possible to do that this or any alternative way?

I think the best approach would be to first define an intermediate scalar space T_complete = FunctionSpace(meshComplete, "Lagrange", 2) on meshComplete, and use PETScDMCollection to interpolate from T to T_complete. Then you can do the scalar-to-vector step with both fields defined on meshComplete. (It’s not clear to me exactly what is meant by projecting from a scalar space to a vector one, but, regardless of the details, it will likely be easier with both fields on the same mesh.)

Thanks @kamensky . it worked :slight_smile: