Package: gmshparser
gmshparser - parse Gmsh .msh file formatPackage author: Jukka Aho (@ahojukka5)Gmshparser is a small Python package which aims to do only one thing: parse Gmsh
mesh file format. Package does not have any external dependencies to other
packages and it aims to be a simple stand-alone solution for a common problem:
how to import mesh to your favourite research FEM code?Project source in GitHub:https://github.com/ahojukka5/gmshparserProject documentation in ReadTheDocs:https://gmshparser.readthedocs.ioProject releases in PyPi:https://pypi.org/project/gmshparserInstalling packageTo install the most recent package from Python Package Index (PyPi), use git:pipinstallgmshparserTo install the development version, you can install the package directly from
the GitHub:pipinstallgit+git://github.com/ahojukka5/gmshparser.gitUsing application programming interfaceTo read mesh intoMeshobject, use commandparse. It takes a filename and
parses the file with the set of parsers, defined inDEFAULT_PARSERS(see
developing package section for more info..!)importgmshparsermesh=gmshparser.parse("data/testmesh.msh")print(mesh)Mesh name: data/testmesh.msh
Mesh version: 4.1
Number of nodes: 6
Minimum node tag: 1
Maximum node tag: 6
Number of node entities: 1
Number of elements: 2
Minimum element tag: 1
Maximum element tag: 2
Number of element entities: 1After reading the model, you can querying your data formmeshobject. For
example, to extract all nodes from the model:forentityinmesh.get_node_entities():fornodeinentity.get_nodes():nid=node.get_tag()ncoords=node.get_coordinates()print("Node id =%s, node coordinates =%s"%(nid,ncoords))Node id = 1, node coordinates = (0.0, 0.0, 0.0)
Node id = 2, node coordinates = (1.0, 0.0, 0.0)
Node id = 3, node coordinates = (1.0, 1.0, 0.0)
Node id = 4, node coordinates = (0.0, 1.0, 0.0)
Node id = 5, node coordinates = (2.0, 0.0, 0.0)
Node id = 6, node coordinates = (2.0, 1.0, 0.0)Extract all elements from the model:forentityinmesh.get_element_entities():eltype=entity.get_element_type()print("Element type:%s"%eltype)forelementinentity.get_elements():elid=element.get_tag()elcon=element.get_connectivity()print("Element id =%s, connectivity =%s"%(elid,elcon))Element type: 3
Element id = 1, connectivity = [1, 2, 3, 4]
Element id = 2, connectivity = [2, 5, 6, 3]If you are writing your FEM stuff with Python, then you have access to the all
relevant properties of the model usingmeshobject. For further information on
how to access nodes, elements, physical groups, and other things what Gmsh
provides, take a look ofdocumentation.Using command line interfacegmshparser can also be useful even if you don't make FEM code in Python. The
above loops used to extract nodes and elements are actually so common, that you
can use them from the command line. This way you can print nodes and elements in
a simpler format with command-line tools, making it easier to read an element
mesh with C ++ or Fortran, for example. To extract nodes:jukka@jukka-XPS-13-9380:~$gmshparserdata/testmesh.mshnodes6
1 0.000000 0.000000 0.000000
2 1.000000 0.000000 0.000000
3 1.000000 1.000000 0.000000
4 0.000000 1.000000 0.000000
5 2.000000 0.000000 0.000000
6 2.000000 1.000000 0.000000To extract elements, use choiceelements. The first line is having the total
number of elements, and the rest of the lines are in formatelement_id element_type element_connectivity. The length of the line naturally depends on
how many nodes the element is having.jukka@jukka-XPS-13-9380:~$gmshparserdata/testmesh.mshelements2
1 3 1 2 3 4
2 3 2 5 6 3Visualizing meshes using gmshparser and matplotlibThe intention of the package is not to visualize meshes. But as it is a quite
common task to visualize 2-dimensional triangluar meshes in acedemic papers,
lecture notes, and things like that, it can be done easily using gmshparser and
matplotlib. There's a helper functiongmshparser.helpers.get_triangles, which
returns a tuple(X, Y, T)which can then be passed to matplotlib to get a mesh
plot:importgmshparsermesh=gmshparser.parse("data/example_mesh.msh")X,Y,T=gmshparser.helpers.get_triangles(mesh)importmatplotlib.pylabaspltplt.figure()plt.triplot(X,Y,T,color='black')plt.axis('equal')plt.axis('off')plt.tight_layout()plt.savefig('docs/example_mesh.svg')Developing packagegmshparser is written such a way, that it's easy to define your own parsers
which are responsible for parsing some section, starting with$SectionNameand
ending with$EndSectionName. For example, a parser which is responsible to
parseMeshFormatsetion isMainFormatParserand it is defined with the
following code:classMeshFormatParser(AbstractParser):@staticmethoddefget_section_name():return"$MeshFormat"@staticmethoddefparse(mesh:Mesh,io:TextIO)->None:s=io.readline().strip().split(" ")mesh.set_version(float(s[0]))mesh.set_ascii(int(s[1])==0)mesh.set_precision(int(s[2]))All the active parsers used in parsing are then appended to the list of parsers
inMainParser, from where they are called when an
appropriateget_section_name()is found from file considered to be parsed. TheMainParseritself is then called inparseto get things done:defparse(filename:str)->Mesh:"""Parse Gmsh .msh file and return `Mesh` object."""mesh=Mesh()mesh.set_name(filename)parser=MainParser()withopen(filename,"r")asio:parser.parse(mesh,io)returnmeshIf you want to learn how to write your own parser, you can e.g. take of look ofNodesParserwhich is responsible for parsing nodes
andElementsParserwhich is responsible for
parsing elements, to get an idea how things are implemented.Contributing to projectLike in all other open source projects, contributions are always welcome to this
project too! If you have some great ideas how to make this package better,
feature requests etc., you can open an issue on gmshparser'sissue
trackeror contact me (ahojukka5@gmail.com) directly.