The program crashes when reading hexahedral mesh using gmshio.read_from_msh

Hello everyone, I used the code below to read the msh file, and the program crashed:

mesh, cell_markers, facet_markers = gmshio.read_from_msh("test.msh", MPI.COMM_WORLD, gdim=3)
Info    : Reading 'test.msh'...
Info    : 9 entities
Info    : 1496 nodes
Info    : 1950 elements
Info    : Done reading 'test.msh'
Invalid rank, error stack:
internal_Issend(60788): MPI_Issend(buf=0x2ebd891, count=1, MPI_BYTE, 1, 1, comm=0x84000005, request=0x2ebbcd4) failed
internal_Issend(60749): Invalid rank has value 1 but must be nonnegative and less than 1
Abort(138019590) on node 0 (rank 0 in comm 416): application called MPI_Abort(comm=0x84000005, 138019590) - process 0

Here is my msh file:https://github.com/French626/mesh/blob/main/test.txt
I am not sure what the reason is and hope to get an answer. Thank you.

Do you have the script that made this msh file? It is quite an ask to ask someone to parse through the whole file looking for issues. Usually this error means that you have not used Physical Curve/Surface/Voljme when generating the mesh.

Hello, this is my script, but the face mesh here is triangular. I exported this script as an opt file through the Gmsh UI, and then added a mesh shape control statement in the opt file: Mesh.SubdivisionAlgorithm = 1; . Finally, I saved it as the hexahedral msh file (with quadrilateral face meshes) that I used above. The reason I used this method is that when I directly add this statement to the script and use the mesh conversion command in the terminal, the resulting msh file is incorrect and throws other errors.

// Gmsh project created on Tue Jul 30 10:39:54 2024
SetFactory("OpenCASCADE");

Circle(1) = {0, 0, 0, 0.5, 0, 2*Pi};

Curve Loop(1) = {1};
Plane Surface(1) = {1};
Extrude {0, 0, 0.3} {Surface{1};Layers {3};Recombine;}

Physical Surface("top_bottom", 4) = {1,3};
Physical Surface("cylinder", 5) = {2};
Physical Volume("v", 6) = {1};

I cant get a hexahedral mesh with those options. I get wedge type elements (triangles and quadrialteral faces).

Could you try:

// Gmsh project created on Tue Jul 30 10:39:54 2024
SetFactory("OpenCASCADE");

Circle(1) = {0, 0, 0, 0.5, 0, 2*Pi};

Curve Loop(1) = {1};
Plane Surface(1) = {1};
Extrude {0, 0, 0.3} {Surface{1};Layers {3};Recombine;}

Physical Surface("top_bottom", 4) = {1,3};
Physical Surface("cylinder", 5) = {2};
Physical Volume("v", 6) = {1};
Mesh.RecombinationAlgorithm = 1;
Mesh.RecombineAll= 2;

This runs nicely for me

from mpi4py import MPI
import dolfinx
mesh, cell_markers, facet_markers = dolfinx.io.gmshio.read_from_msh(
    "mesh.msh", MPI.COMM_WORLD, gdim=3)

Dear Dokken, Sorry for the delayed response, your method is very useful for the cylindrical geometry currently being discussed; however, it may not be suitable for other three-dimensional geometries. I have an example: the script below describes a triangular prism.

// Gmsh project created on Sun Nov 24 14:43:13 2024
SetFactory("OpenCASCADE");
N1 = 10;
N2 = 14;
Point(1) = {0, 0, 0, 1.0};
Point(2) = {0, 1, 0, 1.0};
Point(3) = {1, 0, 0, 1.0};

Line(1) = {1, 2};
Line(2) = {1, 3};
Line(3) = {2, 3};

Transfinite Curve {1, 2} = N1 Using Progression 1;
Transfinite Curve {3} = N2 Using Progression 1;
Curve Loop(1) = {1, 3, -2};
Plane Surface(1) = {1};
Extrude {0, 0, 1} {Surface{1};Layers {10};Recombine;}

Physical Surface("1", 10) = {2};
Physical Surface("2", 11) = {4};
Physical Surface("3", 12) = {3};
Physical Surface("top", 13) = {5};
Physical Surface("bottom", 14) = {1};
Physical Volume("tri", 15) = {1};

When I added the lines Mesh.RecombinationAlgorithm = 1; Mesh.RecombineAll = 2; , I received the following error through the terminal’s mesh conversion command:

Warning : Cannot apply Blossom: odd number of triangles (99) in surface 1

This suggests that when the top and bottom surfaces are triangles, another shape of quadrilateral planar mesh might be needed.

The script below is a 2D triangle before stretching.

// Gmsh project created on Sun Nov 24 14:43:13 2024
SetFactory("OpenCASCADE");
N1 = 10;
N2 = 14;
Point(1) = {0, 0, 0, 1.0};
Point(2) = {0, 1, 0, 1.0};
Point(3) = {1, 0, 0, 1.0};

Line(1) = {1, 2};
Line(2) = {1, 3};
Line(3) = {2, 3};

Transfinite Curve {1, 2} = N1 Using Progression 1;
Transfinite Curve {3} = N2 Using Progression 1;
Curve Loop(1) = {1, 3, -2};
Plane Surface(1) = {1};

Physical Curve("1", 4) = {1};
Physical Curve("2", 5) = {2};
Physical Curve("3", 6) = {3};
Physical Surface("tri", 7) = {1};

By adding the line Mesh.SubdivisionAlgorithm = 1; and using the mesh conversion command in the terminal, I obtained the quadrilateral mesh shown in Figure 1. Based on this, I tried:

Method 1: applying Mesh.SubdivisionAlgorithm = 1; to the triangular prism geometry. However, the msh file obtained through the terminal’s mesh conversion command encounters the following error when using read_from_msh to read it:

Info    : Reading 'mesh.msh'...
Info    : 726 nodes
Info    : 1498 elements
Info    : Done reading 'mesh.msh'

KeyError: 6
Unknown cell type 6.

(I am aware that this error occurs because there are unsupported 6-vertex elements, whereas I want all hexahedra to have 8 vertices.)

Method 2, I applied Mesh.SubdivisionAlgorithm = 1; to the triangular prism geometry and then opened and generated the msh file directly in the GMSH UI. At this point, the msh file encountered the error described in my post when reading it:

Info    : Reading 'mesh.msh'...
Info    : 21 entities
Info    : 4239 nodes
Info    : 4804 elements
Info    : Done reading 'mesh.msh'
Invalid rank, error stack:
internal_Issend(60788): MPI_Issend(buf=0x4097f1a1, count=1, MPI_BYTE, 1, 1, comm=0x84000005, request=0x40949104) failed
internal_Issend(60749): Invalid rank has value 1 but must be nonnegative and less than 1
Abort(607781638) on node 0 (rank 0 in comm 416): application called MPI_Abort(comm=0x84000005, 607781638) - process 0

The visualization of this msh file is shown in Figure 2 (which is the final result I want). However, based on the error results, you can see that the number of elements obtained from the two methods is significantly different.

In summary, the number of elements obtained from stretching Figure 1 to get Figure 2 via Method 1 is definitely not what I want, while the number of elements obtained via Method 2 should be correct. Through my description, you can easily reproduce both methods. I believe we do not need to discuss why the results differ between the two methods; I am simply concerned about why the correct results from Method 2 cannot be read by read_from_msh . Do you have any solutions for this issue?

I think I have solved the problem: I changed the Mesh.SubdivisionAlgorithm parameter from 1 to 2. Now, whether using the mesh conversion command or directly exporting the msh file in the UI, it can be read normally with read_from_msh , and the results are as shown in Figure 2.