I want to programmatically inspect *.msh files (get a number of nodes and elements, possibly also edges and faces). How can I do this with either gmsh
or pygmsh
module? All tutorials I have found so far focus mostly on mesh generation. I can not find any function to read the mesh, not to mention its inspection. Do I have to resort to meshio
?
How to load and inspect a gmsh mesh (*.msh file)
2.6k Views Asked by abukaj At
2
There are 2 best solutions below
1

You can use pygmsh
and meshio
. Load the file with meshio
first and then convert it to a pygmsh
Geometry object. If your file has the gmsh:physical
and gmsh:geometrical
you can define the geometry and then create a mesh.
Here is an example (assumes a simple shape in the mesh file)
import pygmsh
import meshio
mesh = meshio.read("file.msh")
geom = pygmsh.built_in.Geometry()
# Define the nodes
nodes = []
for i in range(mesh.points.shape[0]):
nodes.append(geom.add_point(mesh.points[i], mesh.point_data["gmsh:physical"][i]))
# Define the elements
element_type = list(mesh.cells.keys())[0] # assume only one element type in the mesh
elements = []
for i in range(mesh.cells[element_type].shape[0]):
element_points = []
for j in range(mesh.cells[element_type].shape[1]):
node_index = mesh.cells[element_type][i][j]
element_points.append(nodes[node_index])
elements.append(geom.add_polygon(element_points, mesh.cell_data["gmsh:physical"][i]))
# Define the edges
edges = []
if "line" in mesh.cells:
for i in range(mesh.cells["line"].shape[0]):
edge_points = []
for j in range(mesh.cells["line"].shape[1]):
node_index = mesh.cells["line"][i][j]
edge_points.append(nodes[node_index])
edges.append(geom.add_line(edge_points))
# Define the faces
faces = []
if "quad" in mesh.cells:
for i in range(mesh.cells["quad"].shape[0]):
face_points = []
for j in range(mesh.cells["quad"].shape[1]):
node_index = mesh.cells["quad"][i][j]
face_points.append(nodes[node_index])
faces.append(geom.add_polygon(face_points))
# Generate the mesh
mesh = geom.generate_mesh()
num_nodes = len(nodes)
num_elements = len(elements)
num_edges = len(edges)
num_faces = len(faces)
Personally, I tend to export meshes in CalculiX's
.inp
format by settingMesh.Format = 39;
in my.geo
file.The following code is used to read that
.inp
file, and extract nodes and (C3D20; 2nd order hexaeder elements) elements.This is an excerpt from my
gmsh-inp-filter
program.Edit
The file format is defined here
Writing a parser for the
$Nodes
and$Elements
sections doesn't seem too hard.