Converting simple 2D mesh from gmsh to dolfin

Hey there!

I would like to convert a simple 2D gmsh mesh for use in fenics, t1.geo from the gmsh tutorial, for instance. It seems that dolfin-convert is deprecated, so I decided to use meshio. The suggested format xdmf however is not compatible with dolfin, see https://github.com/nschloe/meshio/issues/260. On the other hand, with the following code

from dolfin import *     
import meshio

msh = meshio.read("t1.msh")
meshio.write("mesh.xml",msh)
mesh = Mesh("mesh.xml")

dolfin is still complaining (“DOLFIN XML can only handle one cell type at a time. Using triangle, discarding vertex, line.”), although the file is readable. However, the mesh is interpreted as 3D.

So, what is a clean way of importing 2D gmsh meshes?

Hi, see: Transitioning from mesh.xml to mesh.xdmf, from dolfin-convert to meshio

The XDMF format of meshio is supported and can be loaded as I show in this reply

Hi dokken, thank you for your answer. However:

  1. It seems that your code is suitable for a 3D mesh only?
  2. Could you please explain the purpose of your code? In particular, the meaning of “tetra”, “triangle”, “cell data”, and the purpose of the variables mvc and mf?

The code I’ve posted there is for a 3D mesh, however, it generalizes to a 2D mesh.
Given this simple geo file

// the square
Point(1) = {0, 0, 0,0.1};
Point(2) = {0, 1, 0,0.1};
Point(3) = {1, 1, 0,0.1};
Point(4) = {1, 0, 0,0.1};
Line(1) = {1, 4};
Line(2) = {4, 3};
Line(3) = {3, 2};
Line(4) = {2, 1};
// creating the surfaces
Line Loop(6) = {2, 3, 4, 1};
Plane Surface(8) = {6};

Physical Surface(2) = {8};

I call gmsh -2 mesh.geo to create the msh file
Then using meshio I load the meshio

import meshio
msh = meshio.read("mesh.msh")

This loads all the data of the mesh. to generate the mesh, I look at the data inside msh.
We need the points, located at msh.points. Since we do a 2D mesh, using triangles, we have to save it with triangles as cell data, with the data, as:
meshio.write("mesh.xdmf", meshio.Mesh(points=msh.points, cells={"triangle": msh.cells["triangle"]})).
To create a file containing the Facet data described with Physical line. We save the meshfunction mf as
meshio.write("mf.xdmf", meshio.Mesh(points=msh.points, cells={"line": msh.cells["line"]}, cell_data={"line": {"name_to_read": msh.cell_data["line"]["gmsh:physical"]}}))
Similarly, if you would like to write the physical surface to file. You have to save it with triangle as cells.

1 Like

Hi dokken, thank you again for your helpful explanation. However, loading mesh.xdmf via

mesh=dolfin.Mesh()
with dolfin.XDMFFile("mesh.xdmf") as infile:
    infile.read(mesh)

dolfin still seems to interpret the mesh as 3D. At least, dolfin.plot(mesh) gives a 3D plot.

EDIT: On the other hand, using dolfin-convert

gmsh -2 mesh.geo -format msh2
dolfin-convert mesh.msh mesh.xml

and reading the mesh via

mesh = dolfin.Mesh('mesh.xml') 

is simply working. So, I think I will use this method until meshio and dolfin have become fully compatible.

Hi freyja, this Depends on how you Create your mesh, there is an meshio option for pruning the z coordinate, see Meshio

Ok, I will try this too. If I’m not mistaken, in your link it is not said how to access that pruning option for meshio-convert? Is it also accessible from within Python? (I installed meshio via pip, and the terminal command meshio-convert is not available.)

Ok, meshio-convert was hiding in ~/.local/bin. In fact, I realized that meshio-convert offers flags for removing lower order cells and the third dimension. So, converting a 2D mesh is as simple as

~/.local/bin/meshio-convert mesh.msh mesh.xdmf -p -z