The length of the array inside the interpolate function wont match the number of DOFs

Hello,
I have always assumed that

mesh = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 2, 2, 
                                       cell_type=dolfinx.mesh.CellType.quadrilateral)

V = dolfinx.fem.functionspace(mesh, ("Lagrange", 1))

def function(x):
    num_nodes2 = x.shape[1]
    print(num_nodes2)
    return np.zeros(num_nodes2)

f = dolfinx.fem.Function(V)
f.interpolate(function) 

the number of nodes num_nodes2 inside the interpolate function is the same as the number of DOFs

num_nodes = V.dofmap.index_map.size_global
print(num_nodes)

but the output in this case is

16
9

And I would like to know why. Thanks

Interpolation is done on a cell level. This means that to interpolate a function into a function space, one computes it cell by cell.

As you have 4 cells, with 4 dofs in each cell, this means that you have 16 interpolation points to consider.

The reason for this is that not every basis function is defined with a functional that is a point evaluation, there are basis functions defined by integral moments, which needs co-variant or contra-variant Piola mappings, which are defined on a cell level.

1 Like

Ok, I see.

The thing is, I would like to assign a value to a specific node, like this

# find specific index 
id_center = next((index for index, node in enumerate(V.tabulate_dof_coordinates()) if np.allclose(node, [0.5, 0.5, 0])), None)

class Expr():
    def __init__(self, t):
        self.t = t

    def __call__(self, x):
        values = np.zeros(x.shape[1])
        values[id_center] = 10 * self.t
        
        return values

value = Expr(1)
f.interpolate(value)

So I can call

value.t = t
f.interpolate(value)

inside a time loop. Is it possible?

Locate the degree of freedom based on its dof coordinate (use V.tabulate_dof_coordinates() to find the relevant coordinate index to access in u.x.array

1 Like