Issue with mapping mesh facets to submesh facets using sub_topology_to_topology

Hello!

I’m trying to map a dolfinx.la.vector defined from the index_map corresponding to the facets (codim = 1) of a mesh to another dolfinx.la.vector defined from a similar index_map but coming from the sub_topology of the entities map returned by dolfinx.mesh.create_submesh. However, the map I get (subt2t in the MWE below) is off since its length does not match the number of local facets in the submesh.

Maybe I just do not understand properly how to use sub_topology_to_topology

It might be clearer with the following MWE. In this example the last values in subt2t are off and therefore the mapping between submesh_vec and mesh_vec does not work.

I am using dolfinx v0.10.0.

import dolfinx as dfx
import numpy as np
from mpi4py import MPI

mesh = dfx.mesh.create_unit_square(MPI.COMM_WORLD, 4, 4)

cdim = mesh.topology.dim
left_cells = dfx.mesh.locate_entities(mesh, 2, lambda x: x[0] < 0.5)
submesh, e_map = dfx.mesh.create_submesh(mesh, cdim, left_cells)[:2]

submesh.topology.create_entities(cdim - 1)
sub_index_map = e_map.sub_topology.index_map(cdim - 1)
local_entities = np.arange(sub_index_map.size_local + sub_index_map.num_ghosts)
subt2t = e_map.sub_topology_to_topology(local_entities, False)

# Map a vector from mesh to submesh
imap = mesh.topology.index_map(cdim - 1)
mesh_vec = dfx.la.vector(imap)
mesh_vec.array[:] = np.arange(len(mesh_vec.array[:]))
submesh_vec = dfx.la.vector(sub_index_map)
submesh_vec.array[:] = mesh_vec.array[subt2t]

I think I know what is the problem with my MWE: e_map.sub_topology_to_topology provides a map between entities of dim e_map.topology.dim, which is 2 in this case, while I want a map between facets of dim 1…

Do you know if there is a way to get a sub_topology_to_topology for entities of dim 1?

I believe the third element returned by create_submesh is the facet map:

submesh, e_map, f_map, v_map = dfx.mesh.create_submesh(mesh, cdim, left_cells)

Then there is a mistake in the documentation ? In the dolfinx.mesh.create_submesh documentation, it says the third output is the vertex map…

You’re right that’s maybe my bad!

This is how I get the facet_to_cell connectivity

            facet_to_cell = mesh.topology.connectivity(
                mesh.topology.dim - 1, mesh.topology.dim
            )

So what you are trying to do is essentially map some data from the facets of the parent mesh to the facets of the submesh.
This is for instance done with scifem.transfer_meshtags_to_submesh

which recently got merged into the DOLFINx core: Add transfer tags to submesh by jorgensd · Pull Request #4172 · FEniCS/dolfinx · GitHub

Great this is exactly what I’m looking for! Many thanks!