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
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
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()
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
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
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()
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
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()
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()