# Interpolation between non-matching mesh boundaries

Hi there,

I am trying to interpolate a solution from the boundary of one domain to the boundary of an adjoining domain, as seen in the pictures.

Domain B is the first mesh and domain A is the second, and for illustration they have been separated: domains A and B have a shared boundary but nonmatching mesh nodes. Basically, I want to solve a PDE in domain A, then use that solution of the PDE as a dirichlet boundary condition for domain B.

My question is: is there a way to do this in FEniCSx?

Note: I cannot (as far as I can tell) use subdomains for this applications. My problem requires that domain B has a very steep anisotropy towards its boundary, and there seems to be no way to create this one sided anisotropy in GMSH (domain A is more complicated than this example and cannot use transfinite meshes.

I attach here a minimum working example

``````import gmsh
from dolfinx import fem, mesh, io
from mpi4py import MPI
import meshio

gmsh.initialize()

# Mesh for domain A
lc = 0.5

gmsh.model.geo.synchronize()

AB_boundary = 1
right_boundary = 2
surface = 1

gmsh.model.mesh.generate(2)
gmsh.write("domain_A.msh")
gmsh.open("domain_A.msh")
gmsh.model.setCurrent("domain_A")

def create_mesh(mesh, cell_type, prune_z=False):
cells = mesh.get_cells_type(cell_type)
cell_data = mesh.get_cell_data("gmsh:physical", cell_type)
points = mesh.points[:,:2] if prune_z else mesh.points
out_mesh = meshio.Mesh(points=points, cells={cell_type: cells}, cell_data={"name_to_read":[cell_data]})
return out_mesh

# Create and save one file for the mesh, and one file for the facets
triangle_mesh_A = create_mesh(msh_A, "triangle", prune_z=True)
line_mesh_A = create_mesh(msh_A, "line", prune_z=True)

meshio.write("mesh_A.xdmf", triangle_mesh_A)
meshio.write("mt_A.xdmf", line_mesh_A)

# Create an XDMF File
with io.XDMFFile(MPI.COMM_WORLD, "mesh_A.xdmf", "r") as xdmf:

mymesh_A.topology.create_connectivity(mymesh_A.topology.dim, mymesh_A.topology.dim-1)

with io.XDMFFile(MPI.COMM_WORLD, "mt.xdmf", "r") as xdmf:

V_A = fem.FunctionSpace(mymesh_A, ("CG", 1))

# Function defined on domain A (usually this is the solution to a PDE)
uh = fem.Function(V_A)
uh.interpolate(lambda x: 1 + x[0]**2 + 2 * x[1]**2)

# Mesh for domain B

progr = 0.8 # coefficient of geometric sequence
nx = 10     # number of evenly spaced nodes on boundary

# Curved loops

# Plane surfaces

# Set transfinite curve
gmsh.model.geo.mesh.setTransfiniteCurve(1, nx, "Progression", progr)
gmsh.model.geo.mesh.setTransfiniteCurve(2, nx, "Progression", -progr)
gmsh.model.geo.mesh.setTransfiniteCurve(3, nx, "Progression", -progr)
gmsh.model.geo.mesh.setTransfiniteCurve(4, nx, "Progression", progr)
gmsh.model.geo.mesh.setTransfiniteCurve(5, nx, "Progression", progr)
gmsh.model.geo.mesh.setTransfiniteCurve(6, nx, "Progression", -progr)
gmsh.model.geo.mesh.setTransfiniteCurve(7, nx, "Progression", -progr)

gmsh.model.geo.mesh.setTransfiniteSurface(1, "AlternateLeft", [1, 2, 6, 5])
gmsh.model.geo.mesh.setTransfiniteSurface(2, "AlternateRight", [5,6,3,4])

gmsh.model.geo.synchronize()
gmsh.model.mesh.generate(2)
gmsh.write("domain_B.msh")
gmsh.open("domain_B.msh")
gmsh.model.setCurrent("domain_B")

# Create and save one file for the mesh, and one file for the facets
triangle_mesh_B = create_mesh(msh_B, "triangle", prune_z=True)
line_mesh_B = create_mesh(msh_B, "line", prune_z=True)

meshio.write("mesh_B.xdmf", triangle_mesh_B)
meshio.write("mt_B.xdmf", line_mesh_B)

# Create an XDMF File
with io.XDMFFile(MPI.COMM_WORLD, "mesh_B.xdmf", "r") as xdmf:

mymesh_B.topology.create_connectivity(mymesh_B.topology.dim, mymesh_B.topology.dim-1)

with io.XDMFFile(MPI.COMM_WORLD, "mt.xdmf", "r") as xdmf:

V_B = fem.FunctionSpace(mymesh_B, ("CG", 1))
``````

See: https://github.com/FEniCS/dolfinx/blob/4af1853f3d46278065003442f04918c30be9d1fc/python/test/unit/fem/test_interpolation.py#L738-L745
or any appropriate version of the FEniCSx version that you are using.

Well… that was easy for some reason I didn’t think that would work, but it did!

``````u1 = fem.Function(V_B)