For a two-phase system, the domain can be categoried into three parts: phase1, phase2 and interface. I try to find DOFs of one phase excluding those on the interface for applying boundary conditions. The following my attempt gives different results in serial and parallel runs, where the serial run is correct. The result of a simplified problem is illustrated by the attached figure.
I first seperate cells by two phases and then get their vertices of each phase. The vertices on the interface can be obtained from the intersection. The vertices of one phase excluding those on the interface can be obtained by the difference between phase vertices and those on the interface. Finally, get corresponding DOFs by using fem.locate_dofs_topological
as
fluid_vertices = mesh.compute_incident_entities(_mesh.topology, Omega_f, tdim, 0)
solid_vertices = mesh.compute_incident_entities(_mesh.topology, Omega_s, tdim, 0)
interface_vertices = np.intersect1d(fluid_vertices, solid_vertices)
Omega_s_inside_vertices = np.setdiff1d(solid_vertices, interface_vertices)
The full MWE with dolfinx v0.8.0:
from mpi4py import MPI
import numpy as np
from dolfinx import fem, mesh, io
comm = MPI.COMM_WORLD
_mesh = mesh.create_unit_square(comm, 50, 50)
tdim, fdim = 2, 1
def solid_domain(x):
return x[1] < 0.5 + 1e-6
num_cells = (_mesh.topology.index_map(tdim).size_local +
_mesh.topology.index_map(tdim).num_ghosts)
Omega_s = mesh.locate_entities(_mesh, tdim, solid_domain)
Omega_f = np.setdiff1d(np.arange(num_cells), Omega_s)
fluid_vertices = mesh.compute_incident_entities(_mesh.topology, Omega_f, tdim, 0)
solid_vertices = mesh.compute_incident_entities(_mesh.topology, Omega_s, tdim, 0)
interface_vertices = np.intersect1d(fluid_vertices, solid_vertices)
Omega_s_inside_vertices = np.setdiff1d(solid_vertices, interface_vertices)
V = fem.functionspace(_mesh, ("Lagrange", 1))
f = fem.Function(V)
_mesh.topology.create_connectivity(0, tdim)
f.x.array[fem.locate_dofs_topological(V, 0, Omega_s_inside_vertices)] = 1
f.x.scatter_forward()
with io.XDMFFile(MPI.COMM_WORLD, f"test.xdmf", "w") as xdmf_s:
xdmf_s.write_mesh(_mesh)
xdmf_s.write_function(f, 0)