Unable to specify BC at a point in FEniCSx

Hello,
I am trying t solve a diffusion problem (Please find the image) in which I want to apply a boundary condition at a point. I have found the discussion regarding this, but it was implemented in FEniCS, I want the solution in FEniCSx.
I have tried something like this but it doesn’t work out.

mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 2, 2)
boundaries_2 = [(5, lambda x: np.isclose([x[0], x[1]], [0, 0]))]

facet_indices_2, facet_markers_2 = [], []
fdim_2 = mesh.topology.dim - 2
for (marker, locator) in boundaries_2:
    facets_2 = dolfinx.mesh.locate_entities(mesh, fdim_2, locator)
    facet_indices_2.append(facets_2)
    facet_markers_2.append(np.full(len(facets_2), marker))
facet_tag_2 = dolfinx.MeshTags(mesh, fdim_2, np.array(np.hstack(facet_indices_2),dtype=np.int32), np.array(np.hstack(facet_markers_2),dtype=np.int32))

It threw this error.


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_65/458078783.py in <module>
      2 fdim_2 = mesh.topology.dim - 2
      3 for (marker, locator) in boundaries_2:
----> 4     facets_2 = dolfinx.mesh.locate_entities(mesh, fdim_2, locator)
      5     facet_indices_2.append(facets_2)
      6     facet_markers_2.append(np.full(len(facets_2), marker))

/usr/local/dolfinx-real/lib/python3.8/dist-packages/dolfinx/mesh.py in locate_entities(mesh, dim, marker)
     41     """
     42 
---> 43     return cpp.mesh.locate_entities(mesh, dim, marker)
     44 
     45 

/tmp/ipykernel_65/2253244396.py in <lambda>(x)
----> 1 boundaries_2 = [(5, lambda x: np.isclose([x[0], x[1]], [0, 0]))]

<__array_function__ internals> in isclose(*args, **kwargs)

/usr/local/lib/python3.8/dist-packages/numpy/core/numeric.py in isclose(a, b, rtol, atol, equal_nan)
   2356     yfin = isfinite(y)
   2357     if all(xfin) and all(yfin):
-> 2358         return within_tol(x, y, atol, rtol)
   2359     else:
   2360         finite = xfin & yfin

/usr/local/lib/python3.8/dist-packages/numpy/core/numeric.py in within_tol(x, y, atol, rtol)
   2337     def within_tol(x, y, atol, rtol):
   2338         with errstate(invalid='ignore'):
-> 2339             return less_equal(abs(x-y), atol + rtol * abs(y))
   2340 
   2341     x = asanyarray(a)

ValueError: operands could not be broadcast together with shapes (2,9) (2,)

Please tell, how can I implement this.
Thank you

This is for instance illustrated in: dolfinx/demo_stokes-taylor-hood.py at main · FEniCS/dolfinx · GitHub
Thus, you can use the syntax:

boundaries_2 = [(5, lambda x: np.isclose(x.T, [0, 0, 0]).all(axis=1))]

or the numpy.logical_and operator:

boundaries_2 = [(5, lambda x: np.logical_and(np.isclose(x[0], 0), np.isclose(x[1], 0)))]
2 Likes

Thanks. It worked for me.
I have one more doubt.

dofs_L = dolfinx.fem.locate_dofs_geometrical(V, lambda x: np.logical_and(np.isclose(x[0], 0), np.isclose(x[1], 0)))
u_L = dolfinx.Function(V)
x = ufl.SpatialCoordinate(mesh)
u_L.interpolate(lambda x: x[0]+3)
u_L.x.scatter_forward()
#u_L = dolfinx.Constant(mesh, 0)
#u_L.x.scatter_forward()
bc_L = dolfinx.DirichletBC(u_L, dofs_L)

In this code, I am specifying the boundary value to 3 at x=0 and y=0.
Why can’t I directly specify the value 3 to this boundary, in this way

u_L = dolfinx.Constant(mesh, 3)
bc_L = dolfinx.DirichletBC(u_L, dofs_L)

This gives NotImplementedError: to me.
Instead of doing this in an indirect way like

u_L.interpolate(lambda x: x[0]+3)
u_L.x.scatter_forward()
bc_L = dolfinx.DirichletBC(u_L, dofs_L)

Is there any simple way to do this, as we have it in FEniCS?

Thanks

As clearly stated by the error message, this has not yet been implemented in DOLFINx, and thus you have to use the indirect method

Understood. Thank you very much.