Hi, if you define “closeness” of facets by vertices, isn’t it then redundant to include normals into the considerations? For the former, the following is a reasonable starting point
from dolfin import *
import numpy as np
def bdry_facets(mesh):
'''Bdry facets given in therm of vertex indices of the mesh'''
fdim = mesh.topology().dim() - 1
f = MeshFunction('size_t', mesh, fdim, 0)
DomainBoundary().mark(f, 1)
mesh.init(fdim, 0)
f2v = mesh.topology()(fdim, 0)
idx = [facet.index() for facet in SubsetIterator(f, 1)]
return zip(map(f2v, idx), idx)
def first(iterable):
'''First element'''
return next(iter(iterable))
# --------------------------------------------------------------------
if __name__ == '__main__':
from scipy.spatial.distance import cdist
import itertools
mesh1, mesh2 = UnitSquareMesh(5, 5), RectangleMesh(Point(1, 0), Point(2, 1), 2, 5)
# Get the distance matrix between boundary points
f1, f2 = bdry_facets(mesh1), bdry_facets(mesh2)
v1, v2 = np.unique(np.hstack(map(first, f1))), np.unique(map(first, f2))
distance_mat = cdist(mesh1.coordinates()[v1], mesh2.coordinates()[v2])
close_enough = 1E-13
# Points that are close enough
close_pairs = [p for p, v in
zip(itertools.product(v1, v2), distance_mat.flat)
if v < close_enough]
close1, close2 = zip(*close_pairs)
# Boundary facets of close points
f1 = filter(lambda ((v0, v1), idx): v0 in close1 and v1 in close1, f1)
f2 = filter(lambda ((v0, v1), idx): v0 in close2 and v1 in close2, f2)
# Change lookup structure for facets of 2nd mesh
keys, values = zip(*f2)
f2 = dict(zip([tuple(sorted(k)) for k in keys], values))
vertex_map = dict(zip(close1, close2))
# Link the facets
facet_map = {}
while f1:
(v0, v1), id1 = f1.pop()
# Mapped facet
mv0, mv1 = vertex_map[v0], vertex_map[v1]
mf = (mv0, mv1) if mv0 < mv1 else (mv1, mv0)
if mf in f2: facet_map[id1] = f2[mf]
assert max(Facet(mesh1, f1).midpoint().distance(Facet(mesh2, f2).midpoint())
for f1, f2 in facet_map.items()) < close_enough