Hi everyone!
I’m using dolfinx 0.5.2 and I need to find the boundary points of a subdomain defined by custom cell tags (the example code is reported below). Specifically, the cells of the subdomain of interest are marked with 1 (cells of the inner rectangle for this case), all the other cells with 0. Thanks in advance for the help!
from shapely import Polygon, Point
import numpy as np
import gmsh
from mpi4py import MPI
from dolfinx.io.gmshio import model_to_mesh
import dolfinx
import dolfinx.plot as plot
import pyvista
rank = MPI.COMM_WORLD.rank
rect1 = np.array([[1, 1], [4, 1], [4, 4], [1, 4], [1, 1]], dtype=np.float64)
rect2 = np.array([[0, 0], [10, 0], [10, 5], [0, 5], [0, 0]], dtype=np.float64)
gmsh.initialize()
rect1_tags = []
rect2_tags = []
for point1, point2 in zip(rect1, rect2):
p1 = gmsh.model.occ.addPoint(point1[0], point1[1], 0, 1)
p2 = gmsh.model.occ.addPoint(point2[0], point2[1], 0, 1)
rect1_tags.append(p1)
rect2_tags.append(p2)
gmsh.model.occ.synchronize()
rect1_wire = []
rect2_wire = []
for ii in range(len(rect1_tags)):
if ii > 0:
l1 = gmsh.model.occ.addLine(rect1_tags[ii - 1], rect1_tags[ii])
l2 = gmsh.model.occ.addLine(rect2_tags[ii - 1], rect2_tags[ii])
rect1_wire.append(l1)
rect2_wire.append(l2)
gmsh.model.occ.synchronize()
gmsh.model.occ.addCurveLoop(rect1_wire, 1)
gmsh.model.occ.addCurveLoop(rect2_wire, 2)
gmsh.model.occ.synchronize()
gmsh.model.occ.addPlaneSurface([1], 1)
gmsh.model.occ.addPlaneSurface([1, 2], 2)
gmsh.model.occ.synchronize()
gmsh.model.addPhysicalGroup(2, [1], 1)
gmsh.model.addPhysicalGroup(2, [2], 2)
gmsh.model.occ.synchronize()
# generate 2D mesh
gmsh.option.setNumber("Mesh.Algorithm", 2)
gmsh.model.mesh.generate(2)
gmsh.model.mesh.optimize("Netgen")
gmsh.model.occ.synchronize()
gmsh.write("mesh.geo_unrolled")
model_rank = 0
mesh_comm = MPI.COMM_WORLD
mesh, ct, ft = model_to_mesh(gmsh.model, mesh_comm, model_rank, gdim=2)
gmsh.finalize()
def create_meshtags(
mesh: dolfinx.mesh.Mesh, poly: Polygon
) -> dolfinx.cpp.mesh.MeshTags_int32:
cells = mesh.topology.connectivity(mesh.topology.dim, 0)
id_cells_inpoly = []
for ii in range(len(cells)):
triangle = Polygon(mesh.geometry.x[cells.links(ii)])
centroid = triangle.centroid
if poly.contains(Point(centroid)):
id_cells_inpoly.append(ii)
values = np.zeros([len(cells), 1], dtype=np.int32)
values[id_cells_inpoly] = 1
meshtags = dolfinx.mesh.meshtags_from_entities(
mesh, mesh.topology.dim, cells, values
)
return meshtags
def plot_meshtags(
mesh: dolfinx.mesh.Mesh,
meshtags: dolfinx.cpp.mesh.MeshTags_int32,
filename: str = "meshtags.png",
):
# Create VTK mesh
cells, types, x = plot.create_vtk_mesh(mesh)
grid = pyvista.UnstructuredGrid(cells, types, x)
# Attach the cells tag data to the pyvita grid
grid.cell_data["Marker"] = meshtags.values
grid.set_active_scalars("Marker")
plotter = pyvista.Plotter()
plotter.add_mesh(grid, show_edges=True, show_scalar_bar=False)
plotter.view_xy()
if not pyvista.OFF_SCREEN:
plotter.show()
else:
plotter.screenshot(filename)
# plot original cell tags
plot_meshtags(mesh, ct)
# create custom cell tags
ct = create_meshtags(mesh, Polygon(rect1))
# plot custom cell tags
plot_meshtags(mesh, ct)