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