def triangle2xml(ifilename, ofilename): """Convert between triangle format (http://www.cs.cmu.edu/~quake/triangle.html) and .xml. The given ifilename should be the prefix for the corresponding .node, and .ele files. """ def get_next_line (fp): """Helper function for skipping comments and blank lines""" line = fp.readline() if line == '': _error("Hit end of file prematurely.") line = line.strip() if not (line.startswith('#') or line == ''): return line return get_next_line(fp) print "Converting from Triangle format {.node, .ele} to DOLFIN XML format" # Open files for suffix in [".node", ".ele"]: if suffix in ifilename and ifilename[-len(suffix):] == suffix: ifilename = ifilename.replace(suffix, "") node_file = open(ifilename+".node", "r") ele_file = open(ifilename+".ele", "r") ofile = open(ofilename, "w") # Read all the nodes nodes = {} num_nodes, dim, attr, bound = map(int, get_next_line(node_file).split()) while len(nodes) < num_nodes: node, x, y = get_next_line(node_file).split()[:3] nodes[int(node)] = (float(x), float(y)) # Read all the triangles tris = {} num_tris, n_per_tri, attrs = map(int, get_next_line(ele_file).split()) while len(tris) < num_tris: tri, n1, n2, n3 = map(int, get_next_line(ele_file).split()[:4]) tris[tri] = (n1, n2, n3) # Write everything out xml_writer.write_header_mesh(ofile, "triangle", 2) xml_writer.write_header_vertices(ofile, num_nodes) node_off = 0 if nodes.has_key(0) else -1 for node, node_t in nodes.iteritems(): xml_writer.write_vertex(ofile, node+node_off, node_t[0], node_t[1], 0.0) xml_writer.write_footer_vertices(ofile) xml_writer.write_header_cells(ofile, num_tris) tri_off = 0 if tris.has_key(0) else -1 for tri, tri_t in tris.iteritems(): write_cell_triangle(ofile, tri+tri_off, tri_t[0] + node_off, tri_t[1] + node_off, tri_t[2] + node_off) xml_writer.write_footer_cells(ofile) xml_writer.write_footer_mesh(ofile) # Close files node_file.close() ele_file.close() ofile.close()
def diffpack2xml(ifilename, ofilename): "Convert from Diffpack tetrahedral grid format to DOLFIN XML." print diffpack2xml.__doc__ # Format strings for MeshFunction XML files meshfunction_header = """\ <?xml version="1.0" encoding="UTF-8"?>\n <dolfin xmlns:dolfin="http://www.fenics.org/dolfin/"> <mesh_function type="uint" dim="%d" size="%d">\n""" meshfunction_entity = " <entity index=\"%d\" value=\"%d\"/>\n" meshfunction_footer = " </mesh_function>\n</dolfin>" # Open files ifile = open(ifilename, "r") ofile = open(ofilename, "w") # Read and analyze header while 1: line = ifile.readline() if not line: _error("Empty file") if line[0] == "#": break if re.search(r"Number of elements", line): num_cells = int(re.match(r".*\s(\d+).*", line).group(1)) if re.search(r"Number of nodes", line): num_vertices = int(re.match(r".*\s(\d+).*", line).group(1)) xml_writer.write_header_mesh(ofile, "tetrahedron", 3) xml_writer.write_header_vertices(ofile, num_vertices) # Read & write vertices and collect markers for vertices vertex_markers = [] unique_vertex_markers = set() for i in range(num_vertices): line = ifile.readline() m = re.match(r"^.*\(\s*(.*)\s*\).*\](.*)$", line) x = map(float, re.split("[\s,]+", m.group(1))) xml_writer.write_vertex(ofile, i, *x) markers = map(int, m.group(2).split()) vertex_markers.append(markers) unique_vertex_markers.update(markers) xml_writer.write_footer_vertices(ofile) xml_writer.write_header_cells(ofile, num_cells) # Output unique vertex markers as individual VertexFunctions unique_vertex_markers.difference_update([0]) for unique_marker in unique_vertex_markers: ofile_marker = open(ofilename.replace(".xml", "") + \ "_marker_" + str(unique_marker)+".xml", "w") xml_writer.write_header_meshfunction(ofile_marker, 0, num_vertices) for ind, markers in enumerate(vertex_markers): if unique_marker in markers: xml_writer.write_entity_meshfunction(ofile_marker, ind, unique_marker) else: xml_writer.write_entity_meshfunction(ofile_marker, ind, 0) xml_writer.write_footer_meshfunction(ofile_marker) # Ignore comment lines while 1: line = ifile.readline() if not line: _error("Empty file") if line[0] == "#": break # Read & write cells and collect cell and face markers cell_markers = [] facet_markers = [] facet_to_vert = [[1,2,3], [0,2,3], [0,1,3], [0,1,2]] vert_to_facet = facet_to_vert # The same! cell_ind = 0 while cell_ind < num_cells: line = ifile.readline() v = line.split() if not v: continue if v[1] != "ElmT4n3D": _error("Only tetrahedral elements (ElmT4n3D) are implemented.") # Store Cell markers cell_markers.append(int(v[2])) # Sort vertex indices cell_indices = sorted(map(lambda x: int(x)-1, v[3:])) xml_writer.write_cell_tetrahedron(ofile, cell_ind, *cell_indices) # Check Facet info process_facet = set(range(4)) for local_vert_ind, global_vert_ind in enumerate(cell_indices): # If no marker is included for vertex skip corresponding facet if not vertex_markers[global_vert_ind]: process_facet.difference_update(facet_to_vert[local_vert_ind]) # Process facets for local_facet in process_facet: # Start with markers from first vertex global_first_vertex = cell_indices[facet_to_vert[local_facet][0]] marker_intersection = set(vertex_markers[global_first_vertex]) # Process the other vertices for local_vert in facet_to_vert[local_facet][1:]: marker_intersection.intersection_update(\ vertex_markers[cell_indices[local_vert]]) if not marker_intersection: break # If not break we have a marker on local_facet else: assert(len(marker_intersection)==1) facet_markers.append((cell_ind, local_facet, \ marker_intersection.pop())) # Bump cell_ind cell_ind += 1 xml_writer.write_footer_cells(ofile) xml_writer.write_header_domains(ofile) # Write facet markers if any if facet_markers: xml_writer.write_header_meshvaluecollection(ofile, "m", 2, \ len(facet_markers), "uint") for cell, local_facet, marker in facet_markers: xml_writer.write_entity_meshvaluecollection(ofile, 2, cell, \ marker, local_facet) xml_writer.write_footer_meshvaluecollection(ofile) xml_writer.write_header_meshvaluecollection(ofile, "m", 3, \ len(cell_markers), "uint") for cell, marker in enumerate(cell_markers): xml_writer.write_entity_meshvaluecollection(ofile, 2, cell, \ marker) xml_writer.write_footer_meshvaluecollection(ofile) xml_writer.write_footer_domains(ofile) xml_writer.write_footer_mesh(ofile) # Close files ifile.close() ofile.close()
def mesh2xml(ifilename, ofilename): """Convert between .mesh and .xml, parser implemented as a state machine: 0 = read 'Dimension' 1 = read dimension 2 = read 'Vertices' 3 = read number of vertices 4 = read next vertex 5 = read 'Triangles' or 'Tetrahedra' 6 = read number of cells 7 = read next cell 8 = done """ print "Converting from Medit format (.mesh) to DOLFIN XML format" # Open files ifile = open(ifilename, "r") ofile = open(ofilename, "w") # Scan file for cell type cell_type = None dim = 0 while 1: # Read next line line = ifile.readline() if not line: break # Remove newline if line[-1] == "\n": line = line[:-1] # Read dimension if line == "Dimension" or line == " Dimension": line = ifile.readline() num_dims = int(line) if num_dims == 2: cell_type = "triangle" dim = 2 elif num_dims == 3: cell_type = "tetrahedron" dim = 3 break # Check that we got the cell type if cell_type == None: _error("Unable to find cell type.") # Step to beginning of file ifile.seek(0) # Write header xml_writer.write_header_mesh(ofile, cell_type, dim) # Current state state = 0 # Write data num_vertices_read = 0 num_cells_read = 0 while 1: # Read next line line = ifile.readline() if not line: break # Skip comments if line[0] == '#': continue # Remove newline if line[-1] == "\n": line = line[:-1] if state == 0: if line == "Dimension" or line == " Dimension": state += 1 elif state == 1: num_dims = int(line) state +=1 elif state == 2: if line == "Vertices" or line == " Vertices": state += 1 elif state == 3: num_vertices = int(line) xml_writer.write_header_vertices(ofile, num_vertices) state +=1 elif state == 4: if num_dims == 2: (x, y, tmp) = line.split() x = float(x) y = float(y) z = 0.0 elif num_dims == 3: (x, y, z, tmp) = line.split() x = float(x) y = float(y) z = float(z) xml_writer.write_vertex(ofile, num_vertices_read, x, y, z) num_vertices_read +=1 if num_vertices == num_vertices_read: xml_writer.write_footer_vertices(ofile) state += 1 elif state == 5: if (line == "Triangles" or line == " Triangles") and num_dims == 2: state += 1 if line == "Tetrahedra" and num_dims == 3: state += 1 elif state == 6: num_cells = int(line) xml_writer.write_header_cells(ofile, num_cells) state +=1 elif state == 7: if num_dims == 2: (n0, n1, n2, tmp) = line.split() n0 = int(n0) - 1 n1 = int(n1) - 1 n2 = int(n2) - 1 xml_writer.write_cell_triangle(ofile, num_cells_read, n0, n1, n2) elif num_dims == 3: (n0, n1, n2, n3, tmp) = line.split() n0 = int(n0) - 1 n1 = int(n1) - 1 n2 = int(n2) - 1 n3 = int(n3) - 1 xml_writer.write_cell_tetrahedron(ofile, num_cells_read, n0, n1, n2, n3) num_cells_read +=1 if num_cells == num_cells_read: xml_writer.write_footer_cells(ofile) state += 1 elif state == 8: break # Check that we got all data if state == 8: print "Conversion done" else: _error("Missing data, unable to convert") # Write footer xml_writer.write_footer_mesh(ofile) # Close files ifile.close() ofile.close()
def triangle2xml(ifilename, ofilename): """Convert between triangle format (http://www.cs.cmu.edu/~quake/triangle.html) and .xml. The given ifilename should be the prefix for the corresponding .node, and .ele files. """ def get_next_line (fp): """Helper function for skipping comments and blank lines""" line = fp.readline() if line == '': _error("Hit end of file prematurely.") line = line.strip() if not (line.startswith('#') or line == ''): return line return get_next_line(fp) print "Converting from Triangle format {.node, .ele} to DOLFIN XML format" # Open files for suffix in [".node", ".ele"]: if suffix in ifilename and ifilename[-len(suffix):] == suffix: ifilename = ifilename.replace(suffix, "") node_file = open(ifilename+".node", "r") ele_file = open(ifilename+".ele", "r") ofile = open(ofilename, "w") try: edge_file = open(ifilename+".edge", "r") print "Found .edge file" except IOError: edge_file = None # Read all the nodes nodes = {} num_nodes, dim, attr, bound = map(int, get_next_line(node_file).split()) while len(nodes) < num_nodes: node, x, y = get_next_line(node_file).split()[:3] nodes[int(node)] = (float(x), float(y)) # Read all the triangles tris = {} tri_attrs = {} num_tris, n_per_tri, attrs = map(int, get_next_line(ele_file).split()) while len(tris) < num_tris: line = get_next_line(ele_file).split() tri, n1, n2, n3 = map(int, line[:4]) # vertices are ordered according to current UFC ordering scheme - # - may change in future! tris[tri] = tuple(sorted((n1, n2, n3))) tri_attrs[tri] = tuple(map(float, line[4:4+attrs])) # Read all the boundary markers from edges edge_markers_global = {} edge_markers_local = [] got_negative_edge_markers = False if edge_file is not None: num_edges, num_edge_markers = map(int, get_next_line(edge_file).split()) if num_edge_markers == 1: while len(edge_markers_global) < num_edges: edge, v1, v2, marker = map(int, get_next_line(edge_file).split()) if marker < 0: got_negative_edge_markers = True edge_markers_global[tuple(sorted((v1, v2)))] = marker if got_negative_edge_markers: print "Some edge markers are negative! dolfin will increase "\ "them by probably 2**32 when loading xml. "\ "Consider using non-negative edge markers only." for tri, vertices in tris.iteritems(): v0, v1, v2 = sorted((vertices[0:3])) try: edge_markers_local.append((tri, 0, \ edge_markers_global[(v1, v2)])) edge_markers_local.append((tri, 1, \ edge_markers_global[(v0, v2)])) edge_markers_local.append((tri, 2, \ edge_markers_global[(v0, v1)])) except IndexError: raise Exception("meshconvert.py: The facet was not found.") elif num_edge_markers == 0: print "...but no markers in it. Ignoring it" else: print "...but %d markers specified in it. It won't be processed."\ %num_edge_markers # Write everything out xml_writer.write_header_mesh(ofile, "triangle", 2) xml_writer.write_header_vertices(ofile, num_nodes) node_off = 0 if nodes.has_key(0) else -1 for node, node_t in nodes.iteritems(): xml_writer.write_vertex(ofile, node+node_off, node_t[0], node_t[1], 0.0) xml_writer.write_footer_vertices(ofile) xml_writer.write_header_cells(ofile, num_tris) tri_off = 0 if tris.has_key(0) else -1 for tri, tri_t in tris.iteritems(): xml_writer.write_cell_triangle(ofile, tri+tri_off, tri_t[0] + node_off, tri_t[1] + node_off, tri_t[2] + node_off) xml_writer.write_footer_cells(ofile) if len(edge_markers_local) > 0: xml_writer.write_header_domains(ofile) xml_writer.write_header_meshvaluecollection(ofile, \ "edge markers", 1, len(edge_markers_local), "uint") for tri, local_edge, marker in edge_markers_local: xml_writer.write_entity_meshvaluecollection(ofile, \ 1, tri+tri_off, marker, local_edge) xml_writer.write_footer_meshvaluecollection(ofile) xml_writer.write_footer_domains(ofile) xml_writer.write_footer_mesh(ofile) for i in range(attrs): afilename = ofilename.replace(".xml", ".attr"+str(i)+".xml") afile = open(afilename, "w") xml_writer.write_header_meshfunction2(afile) xml_writer.write_header_meshvaluecollection(afile, \ "triangle attribs "+str(i), 2, num_tris, "double") for tri, tri_a in tri_attrs.iteritems(): xml_writer.write_entity_meshvaluecollection(afile, \ 2, tri+tri_off, tri_a[i], 0) xml_writer.write_footer_meshvaluecollection(afile) xml_writer.write_footer_meshfunction(afile) print "triangle attributes from .ele file written to "+afilename afile.close() # Close files node_file.close() ele_file.close() if edge_file is not None: edge_file.close() ofile.close()
def starcd2xml(ifilename, ofilename): "Convert from Star-CD tetrahedral grid format to DOLFIN XML." print starcd2xml.__doc__ if not os.path.isfile(ifilename[:-3] + "vrt") or not os.path.isfile(ifilename[:-3] + "cel"): print "StarCD format requires one .vrt file and one .cel file" sys.exit(2) # open output file ofile = open(ofilename, "w") # Open file, the vertices are in a .vrt file ifile = open(ifilename[:-3] + "vrt", "r") write_header_mesh(ofile, "tetrahedron", 3) # Read & write vertices # first, read all lines (need to sweep to times through the file) lines = ifile.readlines() # second, find the number of vertices num_vertices = -1 counter = 0 # nodenr_map is needed because starcd support node numbering like 1,2,4 (ie 3 is missing) nodenr_map = {} for line in lines: nodenr = int(line[0:15]) nodenr_map[nodenr] = counter counter += 1 num_vertices = counter # third, run over all vertices xml_writer.write_header_vertices(ofile, num_vertices) for line in lines: nodenr = int(line[0:15]) vertex0 = float(line[15:31]) vertex1 = float(line[31:47]) vertex2 = float(line[47:63]) xml_writer.write_vertex(ofile, nodenr_map[nodenr], float(vertex0), float(vertex1), float(vertex2)) xml_writer.write_footer_vertices(ofile) # Open file, the cells are in a .cel file ifile = open(ifilename[:-3] + "cel", "r") # Read & write cells # first, read all lines (need to sweep to times through the file) lines = ifile.readlines() # second, find the number of cells num_cells = -1 counter = 0 for line in lines: l = [int(a) for a in line.split()] cellnr, node0, node1, node2, node3, node4, node5, node6, node7, tmp1, tmp2 = l if node4 > 0: if node2 == node3 and node4 == node5 and node5 == node6 and node6 == node7: # these nodes should be equal counter += 1 else: print "The file does contain cells that are not tetraheders. The cell number is ", cellnr, " the line read was ", line else: # triangles on the surface # print "The file does contain cells that are not tetraheders node4==0. The cell number is ", cellnr, " the line read was ", line #sys.exit(2) pass num_cells = counter # third, run over all cells xml_writer.write_header_cells(ofile, num_cells) counter = 0 for line in lines: l = [int(a) for a in line.split()] cellnr, node0, node1, node2, node3, node4, node5, node6, node7, tmp1, tmp2 = l if (node4 > 0): if node2 == node3 and node4 == node5 and node5 == node6 and node6 == node7: # these nodes should be equal xml_writer.write_cell_tetrahedron(ofile, counter, nodenr_map[node0], nodenr_map[node1], nodenr_map[node2], nodenr_map[node4]) counter += 1 xml_writer.write_footer_cells(ofile) xml_writer.write_footer_mesh(ofile) # Close files ifile.close() ofile.close()
def netcdf2xml(ifilename,ofilename): "Convert from NetCDF format to DOLFIN XML." print "Converting from NetCDF format (.ncdf) to DOLFIN XML format" # Open files ifile = open(ifilename, "r") ofile = open(ofilename, "w") cell_type = None dim = 0 # Scan file for dimension, number of nodes, number of elements while 1: line = ifile.readline() if not line: _error("Empty file") if re.search(r"num_dim.*=", line): dim = int(re.match(".*\s=\s(\d+)\s;",line).group(1)) if re.search(r"num_nodes.*=", line): num_vertices = int(re.match(".*\s=\s(\d+)\s;",line).group(1)) if re.search(r"num_elem.*=", line): num_cells = int(re.match(".*\s=\s(\d+)\s;",line).group(1)) if re.search(r"connect1 =",line): break num_dims=dim # Set cell type if dim == 2: cell_type ="triangle" if dim == 3: cell_type ="tetrahedron" # Check that we got the cell type if cell_type == None: _error("Unable to find cell type.") # Write header xml_writer.write_header_mesh(ofile, cell_type, dim) xml_writer.write_header_cells(ofile, num_cells) num_cells_read = 0 # Read and write cells while 1: # Read next line line = ifile.readline() if not line: break connect=re.split("[,;]",line) if num_dims == 2: n0 = int(connect[0])-1 n1 = int(connect[1])-1 n2 = int(connect[2])-1 xml_writer.write_cell_triangle(ofile, num_cells_read, n0, n1, n2) elif num_dims == 3: n0 = int(connect[0])-1 n1 = int(connect[1])-1 n2 = int(connect[2])-1 n3 = int(connect[3])-1 xml_writer.write_cell_tetrahedron(ofile, num_cells_read, n0, n1, n2, n3) num_cells_read +=1 if num_cells == num_cells_read: xml_writer.write_footer_cells(ofile) xml_writer.write_header_vertices(ofile, num_vertices) break num_vertices_read = 0 coords = [[],[],[]] coord = -1 while 1: line = ifile.readline() if not line: _error("Missing data") if re.search(r"coord =",line): break # Read vertices while 1: line = ifile.readline() if not line: break if re.search(r"\A\s\s\S+,",line): coord+=1 print "Found x_"+str(coord)+" coordinates" coords[coord] += line.split() if re.search(r";",line): break # Write vertices for i in range(num_vertices): if num_dims == 2: x = float(re.split(",",coords[0].pop(0))[0]) y = float(re.split(",",coords[1].pop(0))[0]) z = 0 if num_dims == 3: x = float(re.split(",",coords[0].pop(0))[0]) y = float(re.split(",",coords[1].pop(0))[0]) z = float(re.split(",",coords[2].pop(0))[0]) xml_writer.write_vertex(ofile, i, x, y, z) # Write footer xml_writer.write_footer_vertices(ofile) xml_writer.write_footer_mesh(ofile) # Close files ifile.close() ofile.close()
def add_vertex(self, vertex, coords): DataHandler.add_vertex(self, vertex, coords) xml_writer.write_vertex(self.__ofile, vertex, *coords)
def diffpack2xml(ifilename, ofilename): "Convert from Diffpack tetrahedral grid format to DOLFIN XML." print diffpack2xml.__doc__ # Format strings for MeshFunction XML files meshfunction_header = """\ <?xml version="1.0" encoding="UTF-8"?>\n <dolfin xmlns:dolfin="http://www.fenics.org/dolfin/"> <mesh_function type="uint" dim="%d" size="%d">\n""" meshfunction_entity = " <entity index=\"%d\" value=\"%d\"/>\n" meshfunction_footer = " </mesh_function>\n</dolfin>" # Open files ifile = open(ifilename, "r") ofile = open(ofilename, "w") ofile_mat = open(ofilename.split(".")[0]+"_mat.xml", "w") ofile_bi = open(ofilename.split(".")[0]+"_bi.xml", "w") # Read and analyze header while 1: line = ifile.readline() if not line: _error("Empty file") if line[0] == "#": break if re.search(r"Number of elements", line): num_cells = int(re.match(r".*\s(\d+).*", line).group(1)) if re.search(r"Number of nodes", line): num_vertices = int(re.match(r".*\s(\d+).*", line).group(1)) xml_writer.write_header_mesh(ofile, "tetrahedron", 3) xml_writer.write_header_vertices(ofile, num_vertices) ofile_bi.write(meshfunction_header % (0, num_vertices)) ofile_mat.write(meshfunction_header % (3, num_cells)) # Read & write vertices # Note that only first boundary indicator is rewriten into XML for i in range(num_vertices): line = ifile.readline() m = re.match(r"^.*\(\s*(.*)\s*\).*\](.*)$", line) x = re.split("[\s,]+", m.group(1)) xml_writer.write_vertex(ofile, i, x[0], x[1], x[2]) tmp = m.group(2).split() if len(tmp) > 0: bi = int(tmp[0]) else: bi = 0 ofile_bi.write(meshfunction_entity % (i, bi)) xml_writer.write_footer_vertices(ofile) xml_writer.write_header_cells(ofile, num_cells) # Ignore comment lines while 1: line = ifile.readline() if not line: _error("Empty file") if line[0] == "#": break # Read & write cells for i in range(int(num_cells)): line = ifile.readline() v = line.split(); if v[1] != "ElmT4n3D": _error("Only tetrahedral elements (ElmT4n3D) are implemented.") xml_writer.write_cell_tetrahedron(ofile, i, int(v[3])-1, int(v[4])-1, int(v[5])-1, int(v[6])-1) ofile_mat.write(meshfunction_entity % (i, int(v[2]))) xml_writer.write_footer_cells(ofile) xml_writer.write_footer_mesh(ofile) ofile_bi.write(meshfunction_footer) ofile_mat.write(meshfunction_footer) # Close files ifile.close() ofile.close() ofile_mat.close() ofile_bi.close()
def diffpack2xml(ifilename, ofilename): "Convert from Diffpack tetrahedral/triangle grid format to DOLFIN XML." print diffpack2xml.__doc__ # Format strings for MeshFunction XML files meshfunction_header = """\ <?xml version="1.0" encoding="UTF-8"?>\n <dolfin xmlns:dolfin="http://www.fenics.org/dolfin/"> <mesh_function type="uint" dim="%d" size="%d">\n""" meshfunction_entity = " <entity index=\"%d\" value=\"%d\"/>\n" meshfunction_footer = " </mesh_function>\n</dolfin>" # Open files ifile = open(ifilename, "r") ofile = open(ofilename, "w") # Read and analyze header while 1: line = ifile.readline() if not line: _error("Empty file") if line[0] == "#": break if re.search(r"Number of elements", line): num_cells = int(re.match(r".*\s(\d+).*", line).group(1)) if re.search(r"Number of nodes", line): num_vertices = int(re.match(r".*\s(\d+).*", line).group(1)) if re.search(r"Number of space dim.", line): num_dims = int(re.match(r".*\s(\d+).*", line).group(1)) if num_dims == 3: xml_writer.write_header_mesh(ofile, "tetrahedron", 3) elem_type = "ElmT4n3D" write_cell_func = xml_writer.write_cell_tetrahedron else: xml_writer.write_header_mesh(ofile, "triangle", 2) elem_type = "ElmT3n2D" write_cell_func = xml_writer.write_cell_triangle xml_writer.write_header_vertices(ofile, num_vertices) # Read & write vertices and collect markers for vertices vertex_markers = [] unique_vertex_markers = set() for i in range(num_vertices): line = ifile.readline() m = re.match(r"^.*\(\s*(.*)\s*\).*\](.*)$", line) x = map(float, re.split("[\s,]+", m.group(1))) xml_writer.write_vertex(ofile, i, *x) markers = map(int, m.group(2).split()) vertex_markers.append(markers) unique_vertex_markers.update(markers) xml_writer.write_footer_vertices(ofile) xml_writer.write_header_cells(ofile, num_cells) # Output unique vertex markers as individual VertexFunctions unique_vertex_markers.difference_update([0]) for unique_marker in unique_vertex_markers: ofile_marker = open(ofilename.replace(".xml", "") + \ "_marker_" + str(unique_marker)+".xml", "w") xml_writer.write_header_meshfunction(ofile_marker, 0, num_vertices) for ind, markers in enumerate(vertex_markers): if unique_marker in markers: xml_writer.write_entity_meshfunction(ofile_marker, ind, unique_marker) else: xml_writer.write_entity_meshfunction(ofile_marker, ind, 0) xml_writer.write_footer_meshfunction(ofile_marker) # Ignore comment lines while 1: line = ifile.readline() if not line: _error("Empty file") if line[0] == "#": break # Read & write cells and collect cell and face markers cell_markers = [] facet_markers = [] facet_to_vert = [[1,2,3], [0,2,3], [0,1,3], [0,1,2]] vert_to_facet = facet_to_vert # The same! cell_ind = 0 while cell_ind < num_cells: line = ifile.readline() v = line.split() if not v: continue if v[1] != elem_type: _error("Only tetrahedral (ElmT4n3D) and triangular (ElmT3n2D) elements are implemented.") # Store Cell markers cell_markers.append(int(v[2])) # Sort vertex indices cell_indices = sorted(map(lambda x: int(x)-1, v[3:])) write_cell_func(ofile, cell_ind, *cell_indices) if num_dims == 2: cell_ind += 1 continue # Check Facet info process_facet = set(range(4)) for local_vert_ind, global_vert_ind in enumerate(cell_indices): # If no marker is included for vertex skip corresponding facet if not vertex_markers[global_vert_ind]: process_facet.difference_update(facet_to_vert[local_vert_ind]) # Process facets for local_facet in process_facet: # Start with markers from first vertex global_first_vertex = cell_indices[facet_to_vert[local_facet][0]] marker_intersection = set(vertex_markers[global_first_vertex]) # Process the other vertices for local_vert in facet_to_vert[local_facet][1:]: marker_intersection.intersection_update(\ vertex_markers[cell_indices[local_vert]]) if not marker_intersection: break # If not break we have a marker on local_facet else: assert(len(marker_intersection)==1) facet_markers.append((cell_ind, local_facet, \ marker_intersection.pop())) # Bump cell_ind cell_ind += 1 xml_writer.write_footer_cells(ofile) xml_writer.write_header_domains(ofile) # Write facet markers if any if facet_markers: xml_writer.write_header_meshvaluecollection(ofile, "m", 2, \ len(facet_markers), "uint") for cell, local_facet, marker in facet_markers: xml_writer.write_entity_meshvaluecollection(ofile, 2, cell, \ marker, local_facet) xml_writer.write_footer_meshvaluecollection(ofile) xml_writer.write_header_meshvaluecollection(ofile, "m", num_dims, \ len(cell_markers), "uint") for cell, marker in enumerate(cell_markers): xml_writer.write_entity_meshvaluecollection(ofile, num_dims, cell, \ marker) xml_writer.write_footer_meshvaluecollection(ofile) xml_writer.write_footer_domains(ofile) xml_writer.write_footer_mesh(ofile) # Close files ifile.close() ofile.close()