Expected scalar arguments - Plot

Hello everyone.

I am currently trying to plot the displacements solutions of my code as a surface. If I understand, the function ‘u’(displacements, solution) must be u = u(x,y) since I’m using a 2d mesh. This is how I defined u:

V = FunctionSpace(mesh, 'CG',1)
u = Function(V, name='Displacement')

This works if I want to know any specific value of u, but I tried to implement a surface plot as it follows:

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

Xp = np.arange(-0.5, 0.5, 0.01)
Yp = np.arange(0, 1, 0.01)
Xp, Yp = np.meshgrid(Xp, Yp)
up = u(Xp,Yp)

surf = ax.plot_surface(Xp, Yp, up, cmap=cm.coolwarm, linewidth=0, antialiased=False)

fig.colorbar(surf, shrink=0.5, aspect=5)

plt.show
----------------
Traceback (most recent call last):
  File "Robin_Neumann_Edu.py", line 197, in <module>
    up = u(Xp,Yp)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/function/function.py", line 345, in __call__
    raise TypeError("expected scalar arguments for the coordinates")
TypeError: expected scalar arguments for the coordinates

Xp and Yp are vectors whose components are scalars, so, why is this problem happening? Shouldn’t up be the value of u in every (Xp, Yp)?

Thanks again.

Dear @egomezp,

You would need to create a loop and evaluate at each individual point, as eval takes in a single array of the (x, y)-coordinate.

Managed to solve the problem with the following implementation (in case anyone needs it):

interval_x = 0.1
interval_y = 0.1

Xp = np.arange(-0.5, 0.5, interval_x)
Yp = np.arange(0, 1, interval_y)
X, Y = np.meshgrid(Xp, Yp)

Z = np.zeros_like(X)
for i in range(X.shape[0]):
    for j in range(X.shape[1]):
        u.set_allow_extrapolation(True)
        Z[i, j] = u(X[i, j], Y[i, j])

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0, antialiased=False)

fig.colorbar(surf, shrink=0.5, aspect=5)

plt.show()

Thanks for the idea, @dokken