Exemple #1
0
def write_fenics_mesh_points_xdmf(fem_mesh_obj, geometrynode, encoding=ENCODING_ASCII):
    """
        Writes either into hdf5 file or into open mesh file
    """

    numnodes = fem_mesh_obj.FemMesh.NodeCount

    dim = get_MaxDimElementFromList(get_FemMeshObjectElementTypes(fem_mesh_obj))[2]
    effective_dim = dim
    if dim <= 2:
        effective_dim = 2  # effective dim is 2 for dim==1
        geometrynode.set("GeometryType", "XY")
    elif dim == 3:
        geometrynode.set("GeometryType", "XYZ")

    recalc_nodes_ind_dict = {}

    if encoding == ENCODING_ASCII:
        dataitem = ET.SubElement(geometrynode, "DataItem", Dimensions="%d %d" % (numnodes, effective_dim), Format="XML")
        nodes = []
        for (ind, (key, node)) in enumerate(fem_mesh_obj.FemMesh.Nodes.iteritems()):
            nodes.append(node)
            recalc_nodes_ind_dict[key] = ind

        dataitem.text = numpy_array_to_str(points_to_numpy(nodes, dim=effective_dim))
    elif encoding == ENCODING_HDF5:
        pass

    return recalc_nodes_ind_dict
Exemple #2
0
def write_fenics_mesh_points_xdmf(fem_mesh_obj, geometrynode, encoding=ENCODING_ASCII):
    """
        Writes either into hdf5 file or into open mesh file
    """

    numnodes = fem_mesh_obj.FemMesh.NodeCount

    dim = get_MaxDimElementFromList(get_FemMeshObjectElementTypes(fem_mesh_obj))[2]
    effective_dim = dim
    if dim <= 2:
        effective_dim = 2  # effective dim is 2 for dim==1
        geometrynode.set("GeometryType", "XY")
    elif dim == 3:
        geometrynode.set("GeometryType", "XYZ")

    recalc_nodes_ind_dict = {}

    if encoding == ENCODING_ASCII:
        dataitem = ET.SubElement(geometrynode, "DataItem", Dimensions="%d %d" % (numnodes, effective_dim), Format="XML")
        nodes = []
        for (ind, (key, node)) in enumerate(fem_mesh_obj.FemMesh.Nodes.iteritems()):
            nodes.append(node)
            recalc_nodes_ind_dict[key] = ind

        dataitem.text = numpy_array_to_str(points_to_numpy(nodes, dim=effective_dim))
    elif encoding == ENCODING_HDF5:
        pass

    return recalc_nodes_ind_dict
Exemple #3
0
def write_fenics_mesh_volumes_xdmf(fem_mesh_obj,
                                   topologynode,
                                   rd,
                                   encoding=ENCODING_ASCII):
    (num_cells, name_cell, dim_cell) = get_MaxDimElementFromList(
        get_FemMeshObjectElementTypes(fem_mesh_obj))
    element_order = get_FemMeshObjectOrder(fem_mesh_obj)

    FreeCAD_to_Fenics_XDMF_dict = {
        ("Node", 1): ("polyvertex", 1),
        ("Edge", 1): ("polyline", 2),
        ("Edge", 2): ("edge_3", 3),
        ("Triangle", 1): ("triangle", 3),
        ("Triangle", 2): ("tri_6", 6),
        ("Tetra", 1): ("tetrahedron", 4),
        ("Tetra", 2): ("tet_10", 10)
    }

    (topology_type,
     nodes_per_element) = FreeCAD_to_Fenics_XDMF_dict[(name_cell,
                                                       element_order)]

    topologynode.set("TopologyType", topology_type)
    topologynode.set("NumberOfElements", str(num_cells))
    topologynode.set("NodesPerElement", str(nodes_per_element))

    if dim_cell == 3:
        fc_cells = fem_mesh_obj.FemMesh.Volumes
    elif dim_cell == 2:
        fc_cells = fem_mesh_obj.FemMesh.Faces
    elif dim_cell == 1:
        fc_cells = fem_mesh_obj.FemMesh.Edges
    elif dim_cell == 0:
        fc_cells = fem_mesh_obj.FemMesh.Nodes
    else:
        fc_cells = []
        print("Dimension of mesh incompatible with export XDMF function: %d" %
              (dim_cell, ))

    nodeindices = [
        (rd[ind]
         for ind in fem_mesh_obj.FemMesh.getElementNodes(fc_volume_ind))
        for (fen_ind, fc_volume_ind) in enumerate(fc_cells)
    ]
    # FC starts after all other entities, fenics start from 0 to size-1
    # write nodeindices into dict to access them later

    if encoding == ENCODING_ASCII:
        dataitem = etree.SubElement(topologynode,
                                    "DataItem",
                                    NumberType="UInt",
                                    Dimensions="%d %d" %
                                    (num_cells, nodes_per_element),
                                    Format="XML")
        dataitem.text = numpy_array_to_str(tuples_to_numpy(nodeindices))
    elif encoding == ENCODING_HDF5:
        pass
Exemple #4
0
def write_fenics_mesh_xdmf(fem_mesh_obj, outputfile, encoding=ENCODING_ASCII):
    """
        For the export of xdmf.
    """

    FreeCAD_to_Fenics_dict = {
        "Triangle": "triangle",
        "Tetra": "tetrahedron",
        "Hexa": "hexahedron",
        "Edge": "interval",
        "Node": "point",
        "Quadrangle": "quadrilateral",
        "Polygon": "unknown",
        "Polyhedron": "unknown",
        "Prism": "unknown",
        "Pyramid": "unknown",
    }

    print("Converting " + fem_mesh_obj.Label + " to fenics XDMF File")
    print("Dimension of mesh: %d" %
          (get_FemMeshObjectDimension(fem_mesh_obj), ))

    elements_in_mesh = get_FemMeshObjectElementTypes(fem_mesh_obj)
    print("Elements appearing in mesh: %s" % (str(elements_in_mesh), ))
    celltype_in_mesh = get_MaxDimElementFromList(elements_in_mesh)
    (num_cells, cellname_fc, dim_cell) = celltype_in_mesh
    cellname_fenics = FreeCAD_to_Fenics_dict[cellname_fc]
    print("Celltype in mesh -> %s and its Fenics dolfin name: %s" %
          (str(celltype_in_mesh), cellname_fenics))

    root = etree.Element("Xdmf", version="3.0")
    domain = etree.SubElement(root, "Domain")
    grid = etree.SubElement(domain, "Grid", Name="mesh", GridType="Uniform")
    topology = etree.SubElement(grid, "Topology")
    geometry = etree.SubElement(grid, "Geometry")

    # attribute = etree.SubElement(grid, "Attribute") #  for cell functions

    recalc_dict = write_fenics_mesh_points_xdmf(fem_mesh_obj,
                                                geometry,
                                                encoding=encoding)
    write_fenics_mesh_volumes_xdmf(fem_mesh_obj,
                                   topology,
                                   recalc_dict,
                                   encoding=encoding)

    # TODO: improve cell functions support
    # write_fenics_mesh_cellfunctions(fem_mesh_obj, {}, attribute, encoding=encoding)

    fp = open(outputfile, "w")
    fp.write(
        '''<?xml version="1.0"?>\n<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>\n''')
    fp.write(etree.tostring(root, pretty_print=True))
    fp.close()
Exemple #5
0
def write_fenics_mesh_cellfunctions(fem_mesh_obj, mycellvalues, attributenode, encoding=ENCODING_ASCII):
    attributenode.set("AttributeType", "Scalar")
    attributenode.set("Center", "Cell")
    attributenode.set("Name", "f")

    (num_cells, name_cell, dim_cell) = get_MaxDimElementFromList(get_FemMeshObjectElementTypes(fem_mesh_obj))

    if encoding == ENCODING_ASCII:
        dataitem = etree.SubElement(attributenode, "DataItem", Dimensions="%d %d" % (num_cells, 1), Format="XML")
        dataitem.text = numpy_array_to_str(np.random.random((num_cells, 1)))
    elif encoding == ENCODING_HDF5:
        pass
Exemple #6
0
def write_fenics_mesh_cellfunctions(fem_mesh_obj, mycellvalues, attributenode, encoding=ENCODING_ASCII):
    attributenode.set("AttributeType", "Scalar")
    attributenode.set("Center", "Cell")
    attributenode.set("Name", "f")

    (num_cells, name_cell, dim_cell) = get_MaxDimElementFromList(get_FemMeshObjectElementTypes(fem_mesh_obj))

    if encoding == ENCODING_ASCII:
        dataitem = ET.SubElement(attributenode, "DataItem", Dimensions="%d %d" % (num_cells, 1), Format="XML")
        dataitem.text = numpy_array_to_str(np.random.random((num_cells, 1)))
    elif encoding == ENCODING_HDF5:
        pass
Exemple #7
0
def write_fenics_mesh_xdmf(fem_mesh_obj, outputfile, encoding=ENCODING_ASCII):
    """
        For the export of xdmf.
    """

    FreeCAD_to_Fenics_dict = {
        "Triangle": "triangle",
        "Tetra": "tetrahedron",
        "Hexa": "hexahedron",
        "Edge": "interval",
        "Node": "point",
        "Quadrangle": "quadrilateral",

        "Polygon": "unknown", "Polyhedron": "unknown",
        "Prism": "unknown", "Pyramid": "unknown",
    }

    print("Converting " + fem_mesh_obj.Label + " to fenics XDMF File")
    print("Dimension of mesh: %d" % (get_FemMeshObjectDimension(fem_mesh_obj),))

    elements_in_mesh = get_FemMeshObjectElementTypes(fem_mesh_obj)
    print("Elements appearing in mesh: %s" % (str(elements_in_mesh),))
    celltype_in_mesh = get_MaxDimElementFromList(elements_in_mesh)
    (num_cells, cellname_fc, dim_cell) = celltype_in_mesh
    cellname_fenics = FreeCAD_to_Fenics_dict[cellname_fc]
    print("Celltype in mesh -> %s and its Fenics dolfin name: %s" % (str(celltype_in_mesh), cellname_fenics))

    root = etree.Element("Xdmf", version="3.0")
    domain = etree.SubElement(root, "Domain")
    grid = etree.SubElement(domain, "Grid", Name="mesh", GridType="Uniform")
    topology = etree.SubElement(grid, "Topology")
    geometry = etree.SubElement(grid, "Geometry")

    # attribute = etree.SubElement(grid, "Attribute") #  for cell functions

    recalc_dict = write_fenics_mesh_points_xdmf(fem_mesh_obj, geometry, encoding=encoding)
    write_fenics_mesh_volumes_xdmf(fem_mesh_obj, topology, recalc_dict, encoding=encoding)

    # TODO: improve cell functions support
    # write_fenics_mesh_cellfunctions(fem_mesh_obj, {}, attribute, encoding=encoding)

    fp = open(outputfile, "w")
    fp.write('''<?xml version="1.0"?>\n<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>\n''')
    fp.write(etree.tostring(root, pretty_print=True))
    fp.close()
Exemple #8
0
def write_fenics_mesh_volumes_xdmf(fem_mesh_obj, topologynode, rd, encoding=ENCODING_ASCII):
    (num_cells, name_cell, dim_cell) = get_MaxDimElementFromList(get_FemMeshObjectElementTypes(fem_mesh_obj))
    element_order = get_FemMeshObjectOrder(fem_mesh_obj)

    FreeCAD_to_Fenics_XDMF_dict = {
        ("Node", 1): ("polyvertex", 1),
        ("Edge", 1): ("polyline", 2),
        ("Edge", 2): ("edge_3", 3),
        ("Triangle", 1): ("triangle", 3),
        ("Triangle", 2): ("tri_6", 6),
        ("Tetra", 1): ("tetrahedron", 4),
        ("Tetra", 2): ("tet_10", 10)
    }

    (topology_type, nodes_per_element) = FreeCAD_to_Fenics_XDMF_dict[(name_cell, element_order)]

    topologynode.set("TopologyType", topology_type)
    topologynode.set("NumberOfElements", str(num_cells))
    topologynode.set("NodesPerElement", str(nodes_per_element))

    if dim_cell == 3:
        fc_cells = fem_mesh_obj.FemMesh.Volumes
    elif dim_cell == 2:
        fc_cells = fem_mesh_obj.FemMesh.Faces
    elif dim_cell == 1:
        fc_cells = fem_mesh_obj.FemMesh.Edges
    elif dim_cell == 0:
        fc_cells = fem_mesh_obj.FemMesh.Nodes
    else:
        fc_cells = []
        print("Dimension of mesh incompatible with export XDMF function: %d" % (dim_cell,))

    nodeindices = [(rd[ind] for ind in fem_mesh_obj.FemMesh.getElementNodes(fc_volume_ind)) for (fen_ind, fc_volume_ind) in enumerate(fc_cells)]
    # FC starts after all other entities, fenics start from 0 to size-1
    # write nodeindices into dict to access them later

    if encoding == ENCODING_ASCII:
        dataitem = etree.SubElement(topologynode, "DataItem", NumberType="UInt", Dimensions="%d %d" % (num_cells, nodes_per_element), Format="XML")
        dataitem.text = numpy_array_to_str(tuples_to_numpy(nodeindices))
    elif encoding == ENCODING_HDF5:
        pass
Exemple #9
0
def write_fenics_mesh_xdmf(fem_mesh_obj, outputfile, group_values_dict={}, encoding=ENCODING_ASCII):
    """
        For the export of xdmf.
    """

    FreeCAD_to_Fenics_dict = {
        "Triangle": "triangle",
        "Tetra": "tetrahedron",
        "Hexa": "hexahedron",
        "Edge": "interval",
        "Node": "point",
        "Quadrangle": "quadrilateral",

        "Polygon": "unknown", "Polyhedron": "unknown",
        "Prism": "unknown", "Pyramid": "unknown",
    }

    print("Converting " + fem_mesh_obj.Label + " to fenics XDMF File")
    print("Dimension of mesh: %d" % (get_FemMeshObjectDimension(fem_mesh_obj),))

    elements_in_mesh = get_FemMeshObjectElementTypes(fem_mesh_obj)
    print("Elements appearing in mesh: %s" % (str(elements_in_mesh),))
    celltype_in_mesh = get_MaxDimElementFromList(elements_in_mesh)
    (num_cells, cellname_fc, dim_cell) = celltype_in_mesh
    cellname_fenics = FreeCAD_to_Fenics_dict[cellname_fc]
    print("Celltype in mesh -> %s and its Fenics dolfin name: %s" % (str(celltype_in_mesh), cellname_fenics))

    root = ET.Element("Xdmf", version="3.0")
    domain = ET.SubElement(root, "Domain")
    base_grid = ET.SubElement(domain, "Grid", Name="base_mesh", GridType="Uniform")
    base_topology = ET.SubElement(base_grid, "Topology")
    base_geometry = ET.SubElement(base_grid, "Geometry")

    # TODO: for the general mesh: write out topology and geometry in grid node
    # TOOD: for every marked group write own grid node with topology (ref if cells)
    #       geometry ref, attribute

    #####################################
    # write base topo and geometry
    nodes_dict = write_fenics_mesh_points_xdmf(fem_mesh_obj, base_geometry, encoding=encoding)
    write_fenics_mesh_codim_xdmf(fem_mesh_obj, base_topology, nodes_dict, codim=0, encoding=encoding)
    #####################################

    fem_mesh = fem_mesh_obj.FemMesh
    gmshgroups = get_FemMeshObjectMeshGroups(fem_mesh_obj)

    if gmshgroups is not ():
        print('found mesh groups')

    for g in gmshgroups:
        mesh_function_type = fem_mesh.getGroupElementType(g)
        mesh_function_codim = dim_cell - FreeCAD_Group_Dimensions[mesh_function_type]
        mesh_function_name = fem_mesh.getGroupName(g)

        print('group id: %d (label: %s) with element type %s and codim %d'
              % (g, mesh_function_name, mesh_function_type, mesh_function_codim))

        mesh_function_grid = ET.SubElement(domain, "Grid", Name=mesh_function_name + "_mesh", GridType="Uniform")
        mesh_function_topology = ET.SubElement(mesh_function_grid, "Topology")

        mesh_function_topology_description = write_fenics_mesh_codim_xdmf(fem_mesh_obj,
                                                                          mesh_function_topology,
                                                                          nodes_dict,
                                                                          codim=mesh_function_codim, encoding=encoding)

        mesh_function_geometry = ET.SubElement(mesh_function_grid, "Geometry", Reference="XML")
        mesh_function_geometry.text = "/Xdmf/Domain/Grid/Geometry"
        mesh_function_attribute = ET.SubElement(mesh_function_grid, "Attribute")

        elem_dict = {}
        (elem_mark_group, elem_mark_default) = group_values_dict.get(g, (g, -1))

        # TODO: is it better to save all groups each at once or collect all codim equal
        # groups to put them into one function?
        # TODO: nevertheless there has to be a dialog which fixes the default value and the mark value

        for e in fem_mesh.getGroupElements(g):
            elem_dict[e] = elem_mark_group

        val_array = np.array([elem_dict.get(e, elem_mark_default) for e in mesh_function_topology_description])
        topo_array = np.vstack((val_array,)).T
        write_fenics_mesh_scalar_cellfunctions(mesh_function_name,
                                               topo_array,
                                               mesh_function_attribute, encoding=ENCODING_ASCII)

    # TODO: improve cell functions support

    fp = open(outputfile, "w")
    fp.write('''<?xml version="1.0"?>\n<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>\n''')
    fp.write(ET.tostring(root))
    # xml core functionality does not support pretty printing
    # so the output file looks quite ugly
    fp.close()
Exemple #10
0
def write_fenics_mesh_xml(fem_mesh_obj, outputfile):
    """
        For the export, we only have to use the highest dimensional entities and their
        vertices to be exported. (For second order elements, we have to delete the mid element nodes.)
    """

    # TODO: check for second order elements (what to do? deny export or reduce element order?)

    FreeCAD_to_Fenics_dict = {
        "Triangle": "triangle",
        "Tetra": "tetrahedron",
        "Hexa": "hexahedron",
        "Edge": "interval",
        "Node": "point",
        "Quadrangle": "quadrilateral",

        "Polygon": "unknown", "Polyhedron": "unknown",
        "Prism": "unknown", "Pyramid": "unknown",
    }

    print("Converting " + fem_mesh_obj.Label + " to fenics XML File")
    print("Dimension of mesh: %d" % (get_FemMeshObjectDimension(fem_mesh_obj),))

    elements_in_mesh = get_FemMeshObjectElementTypes(fem_mesh_obj)
    print("Elements appearing in mesh: %s" % (str(elements_in_mesh),))
    celltype_in_mesh = get_MaxDimElementFromList(elements_in_mesh)
    (num_cells, cellname_fc, dim_cell) = celltype_in_mesh
    cellname_fenics = FreeCAD_to_Fenics_dict[cellname_fc]
    print("Celltype in mesh -> %s and its Fenics name: %s" % (str(celltype_in_mesh), cellname_fenics))

    root = ET.Element("dolfin", dolfin="http://fenicsproject.org")
    meshchild = ET.SubElement(root, "mesh", celltype=cellname_fenics, dim=str(dim_cell))
    vertices = ET.SubElement(meshchild, "vertices", size=str(fem_mesh_obj.FemMesh.NodeCount))

    for (nodeind, fc_vec) in fem_mesh_obj.FemMesh.Nodes.iteritems():  # python2
        ET.SubElement(
            vertices, "vertex", index=str(nodeind - 1),
            # FC starts from 1, fenics starts from 0 to size-1
            x=str(fc_vec[0]), y=str(fc_vec[1]), z=str(fc_vec[2]))

    cells = ET.SubElement(meshchild, "cells", size=str(num_cells))
    if dim_cell == 3:
        fc_cells = fem_mesh_obj.FemMesh.Volumes
    elif dim_cell == 2:
        fc_cells = fem_mesh_obj.FemMesh.Faces
    elif dim_cell == 1:
        fc_cells = fem_mesh_obj.FemMesh.Edges
    else:
        fc_cells = ()

    for (fen_ind, fc_volume_ind) in enumerate(fc_cells):
        # FC starts after all other entities, fenics start from 0 to size-1
        nodeindices = fem_mesh_obj.FemMesh.getElementNodes(fc_volume_ind)

        cell_args = {}
        for (vi, ni) in enumerate(nodeindices):
            cell_args["v" + str(vi)] = str(ni - 1)
        # generate as many v entries in dict as nodes are listed in cell (works only for first order elements)

        ET.SubElement(cells, cellname_fenics, index=str(fen_ind), **cell_args)

    ET.SubElement(meshchild, "data")

    fp = open(outputfile, "w")
    fp.write(ET.tostring(root))
    # xml core functionality does not support pretty printing
    # so the output file looks quite ugly
    fp.close()
Exemple #11
0
def write_fenics_mesh_xdmf(fem_mesh_obj, outputfile, group_values_dict={}, encoding=ENCODING_ASCII):
    """
        For the export of xdmf.
    """

    FreeCAD_to_Fenics_dict = {
        "Triangle": "triangle",
        "Tetra": "tetrahedron",
        "Hexa": "hexahedron",
        "Edge": "interval",
        "Node": "point",
        "Quadrangle": "quadrilateral",

        "Polygon": "unknown", "Polyhedron": "unknown",
        "Prism": "unknown", "Pyramid": "unknown",
    }

    print("Converting " + fem_mesh_obj.Label + " to fenics XDMF File")
    print("Dimension of mesh: %d" % (get_FemMeshObjectDimension(fem_mesh_obj),))

    elements_in_mesh = get_FemMeshObjectElementTypes(fem_mesh_obj)
    print("Elements appearing in mesh: %s" % (str(elements_in_mesh),))
    celltype_in_mesh = get_MaxDimElementFromList(elements_in_mesh)
    (num_cells, cellname_fc, dim_cell) = celltype_in_mesh
    cellname_fenics = FreeCAD_to_Fenics_dict[cellname_fc]
    print("Celltype in mesh -> %s and its Fenics dolfin name: %s" % (str(celltype_in_mesh), cellname_fenics))

    root = ET.Element("Xdmf", version="3.0")
    domain = ET.SubElement(root, "Domain")
    base_grid = ET.SubElement(domain, "Grid", Name="base_mesh", GridType="Uniform")
    base_topology = ET.SubElement(base_grid, "Topology")
    base_geometry = ET.SubElement(base_grid, "Geometry")

    # TODO: for the general mesh: write out topology and geometry in grid node
    # TOOD: for every marked group write own grid node with topology (ref if cells)
    #       geometry ref, attribute

    #####################################
    # write base topo and geometry
    nodes_dict = write_fenics_mesh_points_xdmf(fem_mesh_obj, base_geometry, encoding=encoding)
    write_fenics_mesh_codim_xdmf(fem_mesh_obj, base_topology, nodes_dict, codim=0, encoding=encoding)
    #####################################

    fem_mesh = fem_mesh_obj.FemMesh
    gmshgroups = get_FemMeshObjectMeshGroups(fem_mesh_obj)

    if gmshgroups is not ():
        print('found mesh groups')

    for g in gmshgroups:
        mesh_function_type = fem_mesh.getGroupElementType(g)
        mesh_function_codim = dim_cell - FreeCAD_Group_Dimensions[mesh_function_type]
        mesh_function_name = fem_mesh.getGroupName(g)

        print('group id: %d (label: %s) with element type %s and codim %d'
              % (g, mesh_function_name, mesh_function_type, mesh_function_codim))

        mesh_function_grid = ET.SubElement(domain, "Grid", Name=mesh_function_name + "_mesh", GridType="Uniform")
        mesh_function_topology = ET.SubElement(mesh_function_grid, "Topology")

        mesh_function_topology_description = write_fenics_mesh_codim_xdmf(fem_mesh_obj,
                                                                          mesh_function_topology,
                                                                          nodes_dict,
                                                                          codim=mesh_function_codim, encoding=encoding)

        mesh_function_geometry = ET.SubElement(mesh_function_grid, "Geometry", Reference="XML")
        mesh_function_geometry.text = "/Xdmf/Domain/Grid/Geometry"
        mesh_function_attribute = ET.SubElement(mesh_function_grid, "Attribute")

        elem_dict = {}
        (elem_mark_group, elem_mark_default) = group_values_dict.get(g, (g, -1))

        # TODO: is it better to save all groups each at once or collect all codim equal
        # groups to put them into one function?
        # TODO: nevertheless there has to be a dialog which fixes the default value and the mark value

        for e in fem_mesh.getGroupElements(g):
            elem_dict[e] = elem_mark_group

        val_array = np.array([elem_dict.get(e, elem_mark_default) for e in mesh_function_topology_description])
        topo_array = np.vstack((val_array,)).T
        write_fenics_mesh_scalar_cellfunctions(mesh_function_name,
                                               topo_array,
                                               mesh_function_attribute, encoding=ENCODING_ASCII)

    # TODO: improve cell functions support

    fp = open(outputfile, "w")
    fp.write('''<?xml version="1.0"?>\n<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>\n''')
    fp.write(ET.tostring(root))
    # xml core functionality does not support pretty printing
    # so the output file looks quite ugly
    fp.close()