How can I find the closest node to an arbitrary coordinates?

I want to impose a DirichletBC for an arbitrary point in my domain.
My idea is to use the approach as in the @kamensky’s answer to: Add interior Point to Dirichlet Boundary, but I guess I need to use exact location of an existing node (or a vertex, I am not sure).

Dirichlet BCs are applied on the DOFs of the FunctionSpace. These coincide with the mesh vertices for P1 elements.

Why not something simple such as the following (not for parallel):

from dolfin import *
import numpy as np

mesh = UnitSquareMesh(16, 16)
V = FunctionSpace(mesh, 'P', 2)  # because P1 would be boring
# get coordinates of DOFs
dof_coords = V.tabulate_dof_coordinates()

# random location
x0 = np.array([0.51241, 0.56245])

# find nearest DOF:
dof = np.argmin(np.linalg.norm(dof_coords - x0, axis=1))

print('dof {}, x = {}'.format(dof, dof_coords[dof]))

# now define a DirichletBC at that point
bc = DirichletBC(V, Constant(123),
                 'near(x[0], {x}) && near(x[1], {y})'.format(x=dof_coords[dof][0], y=dof_coords[dof][1]),
                 'pointwise')

PS: Regarding your linked question, the docstring of the function near is: near(x0: float, x1: float, eps: float = 3e-16). It doesn’t give you the nearest dof but all dofs within abs(x1-x2) < eps.

2 Likes

Thanks a lot, that approach succeeded. :slight_smile:
BTW: why is it unsuitable for parallel computation?

Well, try running the example I posted on 2 processors and have a look at the output:
mpirun -n 2 python test.py

In parallel, the DOFs are distributed on different processors and each processor owns different DOFs.

Good to know. I have hoped that FEniCS uses threads which share exactly the same DoFs…

maybe, I don’t know about the current state of threading in FEniCS. you can achieve what you’re trying with mpi, of course, but you might have to handle this manually