Boundary condition for the backward facing step flow

I have the following domain to apply the Navier Stokes equation as mentioned in here:

I have successfully created this domain (in GMSH) and loaded to the dolfinx using
mesh, cell_tags, facet_tags = gmshio.read_from_msh("mesh3D.msh", MPI.COMM_WORLD, 0, gdim=2)

Here, the lines AB , DC , EF and FA should be no-slip. Hence, as mentioned in the tutorial I’m hoping to change the following code which was originally written for a unit square

def walls(x):
    return np.logical_or(np.isclose(x[1],0), np.isclose(x[1],1))
wall_dofs = locate_dofs_geometrical(V, walls)
u_noslip = np.array((0,) * mesh.geometry.dim, dtype=PETSc.ScalarType)
bc_noslip = dirichletbc(u_noslip, wall_dofs, V)

So, and I’m proposing the following:

def approx_in_range(x, x_min,x_max):
    #Check whether 'x' is within the interval (x_min,x_max) approximately
    return (x_min<=x and x<= x_max) or np.isclose(x, x_min) or np.isclose(x,x_max)

Ax=3
Ay=0
Bx=12
By=0
Cx=12
Cy=5
Dx=0
Dy=5
Ex=0
Ey=3
Fx=3
Fy=3

def walls(x):  
    AB = np.logical_and(approx_in_range(x[0], Ax,Bx),np.isclose(x[1],Ay))
    CD = np.logical_and(approx_in_range(x[0], Dx,Cx),np.isclose(x[1],Cy))
    EF = np.logical_and(approx_in_range(x[0], Ex,Fx),np.isclose(x[1],Ey))
    FA = np.logical_and(np.isclose(x[0],Ax),approx_in_range(x[1], Ay,Fy))
    return AB or CD or EF or FA
wall_dofs = locate_dofs_geometrical(V, walls)
u_noslip = np.array((0,) * mesh.geometry.dim, dtype=PETSc.ScalarType)
bc_noslip = dirichletbc(u_noslip, wall_dofs, V)

def inflow(x):
    return np.logical_and(np.isclose(x[0], 0),approx_in_range(x[1], Ey,Dy))
inflow_dofs = locate_dofs_geometrical(Q, inflow)
bc_inflow = dirichletbc(PETSc.ScalarType(p0), inflow_dofs, Q)

def outflow(x):
    return np.isclose(x[0], Bx)
outflow_dofs = locate_dofs_geometrical(Q, outflow)
bc_outflow = dirichletbc(PETSc.ScalarType(0), outflow_dofs, Q)
bcu = [bc_noslip]
bcp = [bc_inflow, bc_outflow]

But then I get the error:

Can someone please help me to figure out the problem here

You need to use numpy.logical_and and numpy.logical_or to combine vectorized calls to numpy true/false statements.
See: numpy.logical_and — NumPy v1.26 Manual

Thank you.
It worked:

def approx_in_range(x, x_min,x_max):
   
    return np.logical_or(np.logical_or(np.logical_and(x_min<=x , x<= x_max), np.isclose(x, x_min)), np.isclose(x,x_max))