Read simple gmsh msh using read_from_msh in dolfinx

Hello community,

I’m trying to read a simple 2D gmsh msh file in dolfinx, created in gmsh (4.12.2) (gmsh -2 tmp.geo) with tmp.geo being

SetFactory("OpenCASCADE");

r1 = 0.2;
r2 = 0.5;
ll = 2.0;

Circle(1) = {0, 0, 0, r1, 0, Pi};
Circle(2) = {0, 0, 0, r2, 0, Pi};

Extrude {0, -ll, 0} {
  Point{3}; Point{1}; Point{2}; Point{4};
}

Line(7) = {8, 7};
Line(8) = {6, 5};

Curve Loop(1) = {6, 7, -5, -1, 4, 8, -3, 2};
Plane Surface(1) = {1};

Mesh.ElementOrder = 1;
Mesh.MeshSizeFactor = 0.1;

Trying to read it with

#!/usr/bin/env python3
from dolfinx.io import gmshio
from mpi4py import MPI

mesh, _, _ = gmshio.read_from_msh('tmp.msh', MPI.COMM_WORLD, gdim=2)

gives IndexError: index -1 is out of bounds for axis 0 with size 0. The mesh worked in an old pipeline using meshio and MeshEditor in legacy dolfin.

Is a specific msh format required, or do I miss something else?

Thanks. Best,
Marc

Hi

Even if you don’t use it, define a Physical Surface to declare your volume of integration. With that modification gmshio reads the file successfuly.

SetFactory("OpenCASCADE");

r1 = 0.2;
r2 = 0.5;
ll = 2.0;

Circle(1) = {0, 0, 0, r1, 0, Pi};
Circle(2) = {0, 0, 0, r2, 0, Pi};

Extrude {0, -ll, 0} {
  Point{3}; Point{1}; Point{2}; Point{4};
}

Line(7) = {8, 7};
Line(8) = {6, 5};

Curve Loop(1) = {6, 7, -5, -1, 4, 8, -3, 2};
Plane Surface(1) = {1};

//+
Physical Surface("1", 1) = {1}; // This is new in your mesh code

Mesh.ElementOrder = 1;
Mesh.MeshSizeFactor = 0.1;

Running your script now gives

Info    : Reading 'tmp.msh'...
Info    : 17 entities
Info    : 265 nodes
Info    : 419 elements
Info    : Done reading 'temp.msh'

Process finished with exit code 0
3 Likes

The reasoning behind @Jesus_Vellojin answer is that dolfinx.io.gmshio uses the GMSH Python API under the hood to extract the cells of interest using the physical groups:

It is also written explicitly in the docs:
https://docs.fenicsproject.org/dolfinx/v0.7.3/python/generated/dolfinx.io.gmshio.html#dolfinx.io.gmshio.model_to_mesh

In general, gmsh doesn’t store un-tagged surfaces, lines, etc, as written in

1.2.3 Elementary entities vs. physical groups
It is usually convenient to combine elementary geometrical entities into more meaningful groups, e.g. to define some mathematical (“domain”, “boundary with Neumann condition”), functional (“left wing”, “fuselage”) or material (“steel”, “carbon”) properties. Such grouping is done in Gmsh’s geometry module (see Geometry module) through the definition of “physical groups”.
By default in the native Gmsh MSH mesh file format (see Gmsh file formats), as well as in most other mesh formats, if physical groups are defined, the output mesh only contains those elements that belong to at least one physical group. (Different mesh file formats treat physical groups in slightly different ways, depending on their capability to define groups.) To save all mesh elements whether or not physical groups are defined, use the Mesh.SaveAll option (see Mesh options) or specify -save_all on the command line. In some formats (e.g. MSH2), setting Mesh.SaveAll will however discard all physical group definitions.

in

If you save all entities in a GMSH model, you risk overlapping/duplicate cells/facets etc.

1 Like

Perfect, thanks a lot!