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