nschloe / meshio

:spider_web: input/output for many mesh formats
MIT License
1.96k stars 402 forks source link

Writing GMSH with multiple cell types #524

Open angus-g opened 5 years ago

angus-g commented 5 years ago

I'm working on converting a tool that transforms the nodes of a mesh to use meshio for compatibility with multiple gmsh versions. For even a simple case with boundary lines and an interior surface, meshio isn't able to read and then write the mesh file (e.g. square.msh.gz), which is expected per the comment in msh4_1.py "not sure what to do if there are multiple element types present".

It seems as though there's sufficient information in the mesh data structure to do this, however. Each element type can correspond to a separate entity, which is implicitly encoded by the entityDim and entityDim defining a node block of the $Nodes section. Writing the elements can then refer back to these entities.

Unfortunately, this would lose some of the physical mesh data, although that could be another factor for determining when to begin a new entity: group by physical tag, (dimension), and element type.

I could take a look at implementing something along these lines myself, however I'm not super across the internal data structure maintained by meshio (and particularly whether inter-mesh conversion is a goal, and any considerations thereof).

nschloe commented 5 years ago

The mesh you attached is a super-simple triangle mesh and meshio has no problems reading it. You probably meant to upload something else.

angus-g commented 5 years ago

That was intentional. It's a super simple mesh with two cell types, and meshio can't write it back to a file:

>>> import meshio
>>> meshio.__version__
'3.2.12'
>>> mesh = meshio.read('square.msh')
>>> meshio.write('square-out.msh', mesh)
WARNING:root:Binary Gmsh needs c_size_t (got int64). Converting.
WARNING:root:Binary Gmsh needs c_size_t (got int64). Converting.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/nix/store/rj2jpfh9hf6lw5i5c0lnd3kdih443l15-python3-3.7.5-env/lib/python3.7/site-packages/meshio/_h
elpers.py", line 273, in write
    return interface.write(filename, mesh, *args, **_kwargs)
  File "/nix/store/rj2jpfh9hf6lw5i5c0lnd3kdih443l15-python3-3.7.5-env/lib/python3.7/site-packages/meshio/_g
msh/main.py", line 98, in write
    writer.write(filename, mesh, binary=binary)
  File "/nix/store/rj2jpfh9hf6lw5i5c0lnd3kdih443l15-python3-3.7.5-env/lib/python3.7/site-packages/meshio/_g
msh/msh4_1.py", line 272, in write
    write4_1(filename, mesh, binary=binary)
  File "/nix/store/rj2jpfh9hf6lw5i5c0lnd3kdih443l15-python3-3.7.5-env/lib/python3.7/site-packages/meshio/_g
msh/msh4_1.py", line 320, in write4_1
    _write_nodes(fh, mesh.points, mesh.cells, binary)
  File "/nix/store/rj2jpfh9hf6lw5i5c0lnd3kdih443l15-python3-3.7.5-env/lib/python3.7/site-packages/meshio/_g
msh/msh4_1.py", line 370, in _write_nodes
    assert len(cells) == 1, "Can only deal with one cell type for now"
AssertionError: Can only deal with one cell type for now
nschloe commented 5 years ago

Ah yes, okay. Well that still needs to be implemented. Feel free to PR. :smile_cat: