Is it possible to interpolate a function from 1d mesh to 2d mesh

I have something like this

mesh2D = UnitSquareMesh(num_elem, num_elem)
space2D = FunctionSpace(mesh2D, 'P', 1)

mesh1D = IntervalMesh(num_elem, 0.0, 1.0)
space1D = FunctionSpace(mesh1D, 'P', 1)

...

f1D = interpolate(something, space1D)

and now I would like to do something like

f2D = interpolate(f1D, space2D)

Imagine that space1D is the top side of a square space2D , and I want to define function f2D on space2D that will coincide with f1D on the top side of space2D , and take whatever values elsewhere. When I state it like this it maybe sounds a bit unreasonable to want to do something like that, perhaps there is other way to achieve what I want but I wanted to know if it could be done this way.

Note that meshes on space1D and space2D are matching in a sense of having the matching number of elements, but also, if you know some way of doing this if the meshes aren’t matching, that would also be nice.

1 Like

You should consider using the Lagrange Interpolator, see:

It seems to me that those solutions work fine if the two meshes correspond to the same geometry. Maybe there is a solution written in the links you gave me but I am to new to FEniCS to understand them. But at least something compiles now, so maybe I can ask here for further problem. Or should I open new topic? Anyway, here is what confuses me. (I will open new topic if it is needed?)

This is perhaps some small working example:

from __future__ import print_function
from fenics import *

num_elem = 2 

mesh2D = UnitSquareMesh(num_elem, num_elem)
space2D = FunctionSpace(mesh2D, 'P', 1)

mesh1D = IntervalMesh(num_elem, 0.0, 1.0)
space1D = FunctionSpace(mesh1D, 'P', 1)

f1Dexp = Expression('x[0]', degree = 1)
f1D = interpolate(f1Dexp, space1D)

f1Dp = f1D.vector().get_local()
coor = mesh1D.coordinates()
if coor.shape[0] == f1Dp.shape[0]:
  for i in range(len(f1Dp)):
    print ('f(%2g) = %g' % (coor[i][0], f1Dp[i]))
else:
  print ('false dimension')

f2D = interpolate(f1D, space2D)
f2Dp = f2D.vector().get_local()
coor = mesh2D.coordinates()
if coor.shape[0] == f2Dp.shape[0]:
  for i in range(len(f2Dp)):
    print ('f(%2g, %2g) = %g' % (coor[i][0], coor[i][1], f2Dp[i]))
else:
  print ('false dimension')

output is

f( 0) = 1
f(0.5) = 0.5
f( 1) = 0
f( 0,  0) = 0
f(0.5,  0) = 0
f( 1,  0) = 0.5
f( 0, 0.5) = 0
f(0.5, 0.5) = 0.5
f( 1, 0.5) = 1
f( 0,  1) = 0.5
f(0.5,  1) = 1
f( 1,  1) = 1

So two things I don’t understand. First, why are in the first three rows values flipped? I would expect to see

f( 0) = 0
f(0.5) = 0.5
f( 1) = 1

And the other thing is that ‘f(x, 0.5) = x’, and for second coordinate ‘0’ or ‘1’ there are some other values, I guess something that ‘interpolate’ choose to put there. And what I would like is that ‘f(x, 1) = x’, since my ‘mesh1D’ is representing the top side of a square ‘mesh2D’.

Is there a way to do this? Even manually would work for me. Also, the same behaviour exhibits when I change ‘num_elem = 4’ or ‘8’, I put ‘2’ just to make output more readable.

The key here is that the ordering of the mesh coordinates are not the same as the function space degrees of freedom. This becomes quite clear if you use a higher order function space.
Therefore, replace
coor = mesh1D.coordinates() with coor = space1D.tabulate_dof_coordinates().
you can do the same for the 2D space.

I tried to mark both of your answers as solutions but this is not-so-unexpectedly not possible. Perhaps I should have opened another thread. Yes, this is quiet very clear, I should have seen that myself… I might have a follow up question but I will open a new thread if needed. Thank you.

I used the “N1curl” element. How can I do something similar?

LagrangeInterpolator is invalid for “N1curl”