Displaying a mesh created by GMSH

For the unit square domain defined as follows:

domain = mesh.create_unit_square(MPI.COMM_SELF, 8, 8, mesh.CellType.quadrilateral)
tdim = domain.topology.dim

If we want to display the mesh, we can use the code mentioned in here
That is:

topology, cell_types, geometry = plot.create_vtk_mesh(domain, tdim)
grid = pyvista.UnstructuredGrid(topology, cell_types, geometry)

pyvista.set_jupyter_backend("pythreejs")

plotter = pyvista.Plotter()
plotter.add_mesh(grid, show_edges=True)
plotter.view_xy()

if not pyvista.OFF_SCREEN:
    plotter.show()
else:
    pyvista.start_xvfb()
    figure = plotter.screenshot("fundamentals_mesh.png")

My intention is to draw a domain in the GMSH GUI and to display it as I did above.
For that purpose, I was going over this tutorial

Hence, I first created a mesh as below:

And then as mentioned in the tutorial:


from dolfinx.io.gmshio import model_to_mesh
from mpi4py import MPI
mesh, cell_tags, facet_tags = gmshio.read_from_msh("solving.msh", MPI.COMM_WORLD, 0, gdim=3)

But, it gave me an error: No module named 'dolfinx.io.gmshio'; 'dolfinx.io' is not a package
However, I did have the helper function file from somewhere. So, I thought if directly using the read_from_msh function:

def read_from_msh(filename: str, cell_data=False, facet_data=False, gdim=None):
    """
    Reads a mesh from a msh-file and returns the dolfin-x mesh.
    Input:
        filename: Name of msh file
        cell_data: Boolean, True of a mesh tag for cell data should be returned
                   (Default: False)
        facet_data: Boolean, True if a mesh tag for facet data should be
                    returned (Default: False)
        gdim: Geometrical dimension of problem (Default: 3)
    """
    if MPI.COMM_WORLD.rank == 0:
        # Check if gmsh is already initialized
        try:
            current_model = gmsh.model.getCurrent()
        except ValueError:
            current_model = None
            gmsh.initialize()

        gmsh.model.add("Mesh from file")
        gmsh.merge(filename)
    output = gmsh_model_to_mesh(gmsh.model, cell_data=cell_data,
                                facet_data=facet_data, gdim=gdim)
    if MPI.COMM_WORLD.rank == 0:
        if current_model is None:
            gmsh.finalize()
        else:
            gmsh.model.setCurrent(current_model)
    return output


def gmsh_model_to_mesh(model, cell_data=False, facet_data=False, gdim=None):
    """
    Given a GMSH model, create a DOLFIN-X mesh and MeshTags.
        model: The GMSH model
        cell_data: Boolean, True of a mesh tag for cell data should be returned
                   (Default: False)
        facet_data: Boolean, True if a mesh tag for facet data should be
                    returned (Default: False)
        gdim: Geometrical dimension of problem (Default: 3)
    """

    if gdim is None:
        gdim = 3

    if MPI.COMM_WORLD.rank == 0:
        # Get mesh geometry
        x = extract_gmsh_geometry(model)

        # Get mesh topology for each element
        topologies = extract_gmsh_topology_and_markers(model)

        # Get information about each cell type from the msh files
        num_cell_types = len(topologies.keys())
        cell_information = {}
        cell_dimensions = numpy.zeros(num_cell_types, dtype=numpy.int32)
        for i, element in enumerate(topologies.keys()):
            properties = model.mesh.getElementProperties(element)
            name, dim, order, num_nodes, local_coords, _ = properties
            cell_information[i] = {"id": element, "dim": dim,
                                   "num_nodes": num_nodes}
            cell_dimensions[i] = dim

        # Sort elements by ascending dimension
        perm_sort = numpy.argsort(cell_dimensions)

        # Broadcast cell type data and geometric dimension
        cell_id = cell_information[perm_sort[-1]]["id"]
        tdim = cell_information[perm_sort[-1]]["dim"]
        num_nodes = cell_information[perm_sort[-1]]["num_nodes"]
        cell_id, num_nodes = MPI.COMM_WORLD.bcast([cell_id, num_nodes], root=0)

        # Check for facet data and broadcast if found
        if facet_data:
            if tdim - 1 in cell_dimensions:
                num_facet_nodes = MPI.COMM_WORLD.bcast(
                    cell_information[perm_sort[-2]]["num_nodes"], root=0)
                gmsh_facet_id = cell_information[perm_sort[-2]]["id"]
                marked_facets = numpy.asarray(topologies[gmsh_facet_id]["topology"], dtype=numpy.int64)
                facet_values = numpy.asarray(topologies[gmsh_facet_id]["cell_data"], dtype=numpy.int32)
            else:
                raise ValueError("No facet data found in file.")

        cells = numpy.asarray(topologies[cell_id]["topology"], dtype=numpy.int64)
        cell_values = numpy.asarray(topologies[cell_id]["cell_data"], dtype=numpy.int32)

    else:
        cell_id, num_nodes = MPI.COMM_WORLD.bcast([None, None], root=0)
        cells, x = numpy.empty([0, num_nodes], dtype=numpy.int32), numpy.empty([0, gdim])
        cell_values = numpy.empty((0,), dtype=numpy.int32)
        if facet_data:
            num_facet_nodes = MPI.COMM_WORLD.bcast(None, root=0)
            marked_facets = numpy.empty((0, num_facet_nodes), dtype=numpy.int32)
            facet_values = numpy.empty((0,), dtype=numpy.int32)

    # Create distributed mesh
    ufl_domain = ufl_mesh_from_gmsh(cell_id, gdim)
    gmsh_cell_perm = perm_gmsh(to_type(str(ufl_domain.ufl_cell())), num_nodes)
    cells = cells[:, gmsh_cell_perm]
    mesh = create_mesh(MPI.COMM_WORLD, cells, x[:, :gdim], ufl_domain)
    # Create MeshTags for cells
    if cell_data:
        local_entities, local_values = distribute_entity_data(
            mesh, mesh.topology.dim, cells, cell_values)
        mesh.topology.create_connectivity(mesh.topology.dim, 0)
        adj = AdjacencyList_int32(local_entities)
        ct = create_meshtags(mesh, mesh.topology.dim, adj, local_values)
        ct.name = "Cell tags"

    # Create MeshTags for facets
    if facet_data:
        # Permute facets from MSH to Dolfin-X ordering
        # FIXME: This does not work for prism meshes
        facet_type = cell_entity_type(to_type(str(ufl_domain.ufl_cell())),
                                      mesh.topology.dim - 1, 0)
        gmsh_facet_perm = perm_gmsh(facet_type, num_facet_nodes)
        marked_facets = marked_facets[:, gmsh_facet_perm]

        local_entities, local_values = distribute_entity_data(
            mesh, mesh.topology.dim - 1, marked_facets, facet_values)
        mesh.topology.create_connectivity(
            mesh.topology.dim - 1, mesh.topology.dim)
        adj = AdjacencyList_int32(local_entities)
        ft = create_meshtags(mesh, mesh.topology.dim - 1, adj, local_values)
        ft.name = "Facet tags"

    if cell_data and facet_data:
        return mesh, ct, ft
    elif cell_data and not facet_data:
        return mesh, ct
    elif not cell_data and facet_data:
        return mesh, ft
    else:
        return mesh

But then, when I used: mesh, cell_tags, facet_tags = read_from_msh("solving.msh", MPI.COMM_WORLD, 0, gdim=2)
I get the following error:

Can someone please help me to properly handle this issue.

Furthermore, for from dolfinx.io import gmshio gives the error:
cannot import name 'gmshio' from 'dolfinx.io' (/usr/local/dolfinx-real/lib/python3.10/dist-packages/dolfinx/io.py)

I am using dolfinx through Docker and my version is :
0.4.2.0 0eab5343fe8674875f94d50706b033d84fa6d67b

Your docker image is old, i.e. from before the introduction of gmshio; Rewrite GMSH interface (#2261) · FEniCS/dolfinx@1b27281 · GitHub
Please pull dolfimx/dolfinx:v0.5.0, dolfinx/lab:v0.5.0

Secondly, the error you get when copying the helper file indicates that you have not used physical groups when defining your Gmsh model.

1 Like

Thank you so much for always for being patient and proving answers. It is much appreciated Dokken!

Hi Dokken,
It worked. As you mentioned, the physical group and the outdated version was the problem. Thank you very much for helping out