Writes H5M files, cf.
    https://trac.mcs.anl.gov/projects/ITAPS/wiki/MOAB/h5m.

def write(filename, mesh, add_global_ids=True):
    """Writes H5M files, cf.
    https://trac.mcs.anl.gov/projects/ITAPS/wiki/MOAB/h5m.
    """
    import h5py

    f = h5py.File(filename, "w")

    tstt = f.create_group("tstt")

    # The base index for h5m is 1.
    global_id = 1

    # add nodes
    nodes = tstt.create_group("nodes")
    coords = nodes.create_dataset("coordinates", data=mesh.points)
    coords.attrs.create("start_id", global_id)
    global_id += len(mesh.points)

    # Global tags
    tstt_tags = tstt.create_group("tags")

    # The GLOBAL_ID associated with a point is used to identify points if
    # distributed across several processes. mbpart automatically adds them,
    # too.
    # Copy to pd to avoid changing point_data. The items are not deep-copied.
    pd = mesh.point_data.copy()
    if "GLOBAL_ID" not in pd and add_global_ids:
        pd["GLOBAL_ID"] = numpy.arange(1, len(mesh.points) + 1)

    # add point data
    if pd:
        tags = nodes.create_group("tags")
    for key, data in pd.items():
        if len(data.shape) == 1:
            dtype = data.dtype
            tags.create_dataset(key, data=data)
        else:
            # H5M doesn't accept n-x-k arrays as data; it wants an n-x-1
            # array with k-tuples as entries.
            n, k = data.shape
            dtype = numpy.dtype((data.dtype, (k,)))
            dset = tags.create_dataset(key, (n,), dtype=dtype)
            dset[:] = data

        # Create entry in global tags
        g = tstt_tags.create_group(key)
        g["type"] = dtype
        # Add a class tag:
        # From
        # <http://lists.mcs.anl.gov/pipermail/moab-dev/2015/007104.html>:
        # ```
        # /* Was dense tag data in mesh database */
        #  define mhdf_DENSE_TYPE   2
        # /** \brief Was sparse tag data in mesh database */
        # #define mhdf_SPARSE_TYPE  1
        # /** \brief Was bit-field tag data in mesh database */
        # #define mhdf_BIT_TYPE     0
        # /** \brief Unused */
        # #define mhdf_MESH_TYPE    3
        #
        g.attrs["class"] = 2

    # add elements
    elements = tstt.create_group("elements")

    elem_dt = h5py.special_dtype(
        enum=(
            "i",
            {
                "Edge": 1,
                "Tri": 2,
                "Quad": 3,
                "Polygon": 4,
                "Tet": 5,
                "Pyramid": 6,
                "Prism": 7,
                "Knife": 8,
                "Hex": 9,
                "Polyhedron": 10,
            },
        )
    )

    tstt["elemtypes"] = elem_dt

    tstt.create_dataset(
        "history",
        data=[
            __name__.encode("utf-8"),
            __about__.__version__.encode("utf-8"),
            str(datetime.now()).encode("utf-8"),
        ],
    )

    # number of nodes to h5m name, element type
    meshio_to_h5m_type = {
        "line": {"name": "Edge2", "type": 1},
        "triangle": {"name": "Tri3", "type": 2},
        "tetra": {"name": "Tet4", "type": 5},
    }
    for key, data in mesh.cells.items():
        if key not in meshio_to_h5m_type:
            logging.warning("Unsupported H5M element type '%s'. Skipping.", key)
            continue
        this_type = meshio_to_h5m_type[key]
        elem_group = elements.create_group(this_type["name"])
        elem_group.attrs.create("element_type", this_type["type"], dtype=elem_dt)
        # h5m node indices are 1-based
        conn = elem_group.create_dataset("connectivity", data=(data + 1))
        conn.attrs.create("start_id", global_id)
        global_id += len(data)

    # add cell data
    if mesh.cell_data:
        tags = elem_group.create_group("tags")
        for key, value in mesh.cell_data.items():
            tags.create_dataset(key, data=value)

    # add empty set -- MOAB wants this
    sets = tstt.create_group("sets")
    sets.create_group("tags")

    # set max_id
    tstt.attrs.create("max_id", global_id, dtype="u8")
    return