That is because you are not making your mesh properly in pygmsh
. You need to use boolean fragments in 3D (using opencascade and not built_in). Additionaly, some handling of these unions are required when reading in the mesh.
For generating a simple geometry consisting of a box inside another, with unique markers for each box:
import pygmsh
import meshio
geom = pygmsh.opencascade.Geometry()
box0 = geom.add_box([0.0, 0, 0], [1, 1, 1], char_length=0.05)
box1 = geom.add_box([0.25, 0.25, 0.25], [0.4, 0.3, 0.2], char_length=0.05)
frags = geom.boolean_fragments([box0],[box1])
geom.add_raw_code("Physical Volume(1) = {13};")
geom.add_raw_code("Physical Volume(2) = {14};")
msh = pygmsh.generate_mesh(geom, geo_filename = "mesh.msh")
import numpy as np
tetra_cells = None
for cell in msh.cells:
if cell.type == "tetra":
# Collect the individual meshes
if tetra_cells is None:
tetra_cells = cell.data
else:
tetra_cells = np.vstack((tetra_cells, cell.data))
tetra_data = None
for key in msh.cell_data_dict["gmsh:physical"].keys():
if key == "tetra":
tetra_data = msh.cell_data_dict["gmsh:physical"][key]
# Create tetra mesh with cell data attached
tetra_mesh = meshio.Mesh(points=msh.points, cells={"tetra": tetra_cells},
cell_data={"name_to_read":[tetra_data]})
meshio.write("mesh.xdmf", tetra_mesh)
To load the mesh and corresponding cell_data into dolfin, you can do the following:
from dolfin import MPI, MeshValueCollection, cpp, Mesh, XDMFFile
mesh_file = XDMFFile(MPI.comm_world, "mesh.xdmf")
mesh = Mesh()
mesh_file.read(mesh);
mvc = MeshValueCollection("size_t", mesh, 3)
mesh_file.read(mvc, "name_to_read")
mf = cpp.mesh.MeshFunctionSizet(mesh, mvc)