def ReadMsh(filename): """ Read a Gmsh msh file """ fileHandle = open(filename, "rb") basename = filename.split(".")[0] hasHalo = filehandling.FileExists(basename + ".halo") # Read the MeshFormat section line = ReadNonCommentLine(fileHandle) assert (line == "$MeshFormat") line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert (len(lineSplit) == 3) version = lineSplit[0] fileType = int(lineSplit[1]) dataSize = int(lineSplit[2]) if version[0] == "4" and version < "4.1": raise Exception("gmshtools doesn't handle msh4 with minor version 0") if fileType == 1: # Binary format if version[0] == "4": mesh = ReadBinaryMshV4(fileHandle, dataSize) elif version[0] == "2": mesh = ReadBinaryMshV2(fileHandle, dataSize) else: raise Exception("Unknown gmsh major version") elif fileType == 0: # ASCII format if version[0] == "4": mesh = ReadAsciiMshV4(fileHandle) elif version[0] == "2": mesh = ReadAsciiMshV2(fileHandle) else: raise Exception("Unknown gmsh major version") else: raise Exception("File type " + str(fileType) + " not recognised") fileHandle.close() if hasHalo: # Read the .halo file debug.dprint("Reading .halo file") if mesh_halos.HaloIOSupport(): halos = mesh_halos.ReadHalos(basename + ".halo") mesh.SetHalos(halos) else: debug.deprint("Warning: No .halo I/O support") return mesh
def ReadTriangle(baseName): """ Read triangle files with the given base name, and return it as a mesh """ def StripComment(line): if "#" in line: return line.split("#")[0] else: return line def ReadNonCommentLine(fileHandle): line = fileHandle.readline() while len(line) > 0: line = StripComment(line).strip() if len(line) > 0: return line line = fileHandle.readline() return line # Determine which files exist assert(filehandling.FileExists(baseName + ".node")) hasBound = filehandling.FileExists(baseName + ".bound") hasEdge = filehandling.FileExists(baseName + ".edge") hasFace = filehandling.FileExists(baseName + ".face") hasEle = filehandling.FileExists(baseName + ".ele") hasHalo = filehandling.FileExists(baseName + ".halo") # Read the .node file nodeHandle = open(baseName + ".node", "r") # Extract the meta data line = ReadNonCommentLine(nodeHandle) lineSplit = line.split() assert(len(lineSplit) == 4) nNodes = int(lineSplit[0]) assert(nNodes >= 0) dim = int(lineSplit[1]) assert(dim >= 0) nNodeAttrs = int(lineSplit[2]) assert(nNodeAttrs >= 0) nNodeIds = int(lineSplit[3]) assert(nNodeIds >= 0) mesh = meshes.Mesh(dim) # Read the nodes debug.dprint("Reading .node file") for line in nodeHandle.readlines(): line = StripComment(line) if len(line.strip()) == 0: continue lineSplit = line.split() assert(len(lineSplit) == 1 + dim + nNodeAttrs + nNodeIds) mesh.AddNodeCoord([float(coord) for coord in lineSplit[1:dim + 1]]) assert(mesh.NodeCoordsCount() == nNodes) nodeHandle.close() if hasBound and dim == 1: # Read the .bound file debug.dprint("Reading .bound file") boundHandle = open(baseName + ".bound", "r") # Extract the meta data line = ReadNonCommentLine(boundHandle) lineSplit = line.split() assert(len(lineSplit) == 2) nBounds = int(lineSplit[0]) assert(nBounds >= 0) nBoundIds = int(lineSplit[1]) assert(nBoundIds >= 0) # Read the bounds for line in boundHandle.readlines(): line = StripComment(line) if len(line.strip()) == 0: continue lineSplit = line.split() assert(len(lineSplit) == 2 + nBoundIds) element = elements.Element() for node in lineSplit[1:2]: element.AddNode(int(node) - 1) element.SetIds([int(boundId) for boundId in lineSplit[2:]]) mesh.AddSurfaceElement(element) assert(mesh.SurfaceElementCount() == nBounds) boundHandle.close() if hasEdge and dim == 2: # Read the .edge file debug.dprint("Reading .edge file") edgeHandle = open(baseName + ".edge", "r") # Extract the meta data line = ReadNonCommentLine(edgeHandle) lineSplit = line.split() assert(len(lineSplit) == 2) nEdges = int(lineSplit[0]) assert(nEdges >= 0) nEdgeIds = int(lineSplit[1]) assert(nEdgeIds >= 0) # Read the edges for line in edgeHandle.readlines(): line = StripComment(line) if len(line.strip()) == 0: continue lineSplit = line.split() assert(len(lineSplit) == 3 + nEdgeIds) element = elements.Element() for node in lineSplit[1:3]: element.AddNode(int(node) - 1) element.SetIds([int(edgeId) for edgeId in lineSplit[3:]]) mesh.AddSurfaceElement(element) assert(mesh.SurfaceElementCount() == nEdges) edgeHandle.close() if hasFace and dim > 2: # Read the .face file debug.dprint("Reading .face file") faceHandle = open(baseName + ".face", "r") # Extract the meta data line = ReadNonCommentLine(faceHandle) lineSplit = line.split() assert(len(lineSplit) == 2) nFaces = int(lineSplit[0]) assert(nFaces >= 0) nFaceIds = int(lineSplit[1]) assert(nFaceIds >= 0) # Read the faces for line in faceHandle.readlines(): line = StripComment(line) if len(line.strip()) == 0: continue lineSplit = line.split() assert(len(lineSplit) >= 4 + nFaceIds) element = elements.Element() for node in lineSplit[1:len(lineSplit) - nFaceIds]: element.AddNode(int(node) - 1) element.SetIds([int(faceId) for faceId in lineSplit[len(lineSplit) - nFaceIds:]]) mesh.AddSurfaceElement(element) assert(mesh.SurfaceElementCount() == nFaces) faceHandle.close() if hasEle: # Read the .ele file debug.dprint("Reading .ele file") eleHandle = open(baseName + ".ele", "r") # Extract the meta data line = ReadNonCommentLine(eleHandle) lineSplit = line.split() assert(len(lineSplit) == 3) nEles = int(lineSplit[0]) assert(nEles >= 0) nNodesPerEle = int(lineSplit[1]) assert(nNodesPerEle >= 0) nEleIds = int(lineSplit[2]) assert(nEleIds >= 0) # Read the eles for line in eleHandle.readlines(): line = StripComment(line) if len(line.strip()) == 0: continue lineSplit = line.split() assert(len(lineSplit) == 1 + nNodesPerEle + nEleIds) element = elements.Element() for node in lineSplit[1:len(lineSplit) - nEleIds]: element.AddNode(int(node) - 1) element.SetIds([int(eleId) for eleId in lineSplit[len(lineSplit) - nEleIds:]]) mesh.AddVolumeElement(element) assert(mesh.VolumeElementCount() == nEles) eleHandle.close() if hasHalo: # Read the .halo file debug.dprint("Reading .halo file") if mesh_halos.HaloIOSupport(): halos = mesh_halos.ReadHalos(baseName + ".halo") mesh.SetHalos(halos) else: debug.deprint("Warning: No .halo I/O support") return mesh
def ReadMsh(filename): """ Read a Gmsh msh file """ def ReadNonCommentLine(fileHandle): line = fileHandle.readline() while len(line) > 0: line = line.strip() if len(line) > 0: return line line = fileHandle.readline() return line fileHandle = open(filename, "r") basename = filename.split(".")[0] hasHalo = filehandling.FileExists(basename + ".halo") # Read the MeshFormat section line = ReadNonCommentLine(fileHandle) assert(line == "$MeshFormat") line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert(len(lineSplit) == 3) version = float(lineSplit[0]) fileType = int(lineSplit[1]) dataSize = int(lineSplit[2]) if fileType == 1: # Binary format if dataSize == 4: realFormat = "f" elif dataSize == 8: realFormat = "d" else: raise Exception("Unrecognised real size " + str(dataSize)) iArr = array.array("i") iArr.fromfile(fileHandle, 1) if iArr[0] == 1: swap = False else: iArr.byteswap() if iArr[0] == 1: swap = True else: raise Exception("Invalid one byte") line = ReadNonCommentLine(fileHandle) assert(line == "$EndMeshFormat") # Read the Nodes section line = ReadNonCommentLine(fileHandle) assert(line == "$Nodes") line = ReadNonCommentLine(fileHandle) nNodes = int(line) # Assume dense node IDs, but not necessarily ordered seenNode = [False for i in range(nNodes)] nodeIds = [] nodes = [] lbound = [calc.Inf() for i in range(3)] ubound = [-calc.Inf() for i in range(3)] for i in range(nNodes): iArr = array.array("i") rArr = array.array(realFormat) iArr.fromfile(fileHandle, 1) rArr.fromfile(fileHandle, 3) if swap: iArr.byteswap() rArr.byteswap() nodeId = iArr[0] coord = rArr assert(nodeId > 0) assert(not seenNode[nodeId - 1]) seenNode[nodeId - 1] = True nodeIds.append(nodeId) nodes.append(coord) for j in range(3): lbound[j] = min(lbound[j], coord[j]) ubound[j] = max(ubound[j], coord[j]) line = ReadNonCommentLine(fileHandle) assert(line == "$EndNodes") nodes = utils.KeyedSort(nodeIds, nodes) bound = bounds.BoundingBox(lbound, ubound) indices = bound.UsedDimIndices() dim = len(indices) if dim < 3: nodes = [[coord[index] for index in indices] for coord in nodes] mesh = meshes.Mesh(dim) mesh.AddNodeCoords(nodes) # Read the Elements section line = ReadNonCommentLine(fileHandle) assert(line == "$Elements") line = ReadNonCommentLine(fileHandle) nEles = int(line) i = 0 while i < nEles: iArr = array.array("i") iArr.fromfile(fileHandle, 3) if swap: iArr.byteswap() typeId = iArr[0] nSubEles = iArr[1] nIds = iArr[2] type = GmshElementType(gmshElementTypeId = typeId) for j in range(nSubEles): iArr = array.array("i") iArr.fromfile(fileHandle, 1 + nIds + type.GetNodeCount()) if swap: iArr.byteswap() eleId = iArr[0] assert(eleId > 0) ids = iArr[1:1 + nIds] nodes = FromGmshNodeOrder(utils.OffsetList(iArr[-type.GetNodeCount():], -1), type) element = elements.Element(nodes, ids) if type.GetDim() == dim - 1: mesh.AddSurfaceElement(element) elif type.GetDim() == dim: mesh.AddVolumeElement(element) else: debug.deprint("Warning: Element of type " + str(type) + " encountered in " + str(dim) + " dimensions") i += nSubEles assert(i == nEles) line = ReadNonCommentLine(fileHandle) assert(line == "$EndElements") elif fileType == 0: # ASCII format line = ReadNonCommentLine(fileHandle) assert(line == "$EndMeshFormat") # Read the Nodes section line = ReadNonCommentLine(fileHandle) assert(line == "$Nodes") line = ReadNonCommentLine(fileHandle) nNodes = int(line) # Assume dense node IDs, but not necessarily ordered seenNode = [False for i in range(nNodes)] nodeIds = [] nodes = [] lbound = [calc.Inf() for i in range(3)] ubound = [-calc.Inf() for i in range(3)] for i in range(nNodes): line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert(len(lineSplit) == 4) nodeId = int(lineSplit[0]) coord = [float(comp) for comp in lineSplit[1:]] assert(nodeId > 0) assert(not seenNode[nodeId - 1]) seenNode[nodeId - 1] = True nodeIds.append(nodeId) nodes.append(coord) for j in range(3): lbound[j] = min(lbound[j], coord[j]) ubound[j] = max(ubound[j], coord[j]) line = ReadNonCommentLine(fileHandle) assert(line == "$EndNodes") nodes = utils.KeyedSort(nodeIds, nodes) bound = bounds.BoundingBox(lbound, ubound) indices = bound.UsedDimIndices() dim = len(indices) if dim < 3: nodes = [[coord[index] for index in indices] for coord in nodes] mesh = meshes.Mesh(dim) mesh.AddNodeCoords(nodes) # Read the Elements section line = ReadNonCommentLine(fileHandle) assert(line == "$Elements") line = ReadNonCommentLine(fileHandle) nEles = int(line) for i in range(nEles): line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert(len(lineSplit) > 3) eleId = int(lineSplit[0]) assert(eleId > 0) typeId = int(lineSplit[1]) nIds = int(lineSplit[2]) type = GmshElementType(gmshElementTypeId = typeId) ids = [int(id) for id in lineSplit[3:3 + nIds]] nodes = FromGmshNodeOrder([int(node) - 1 for node in lineSplit[-type.GetNodeCount():]], type) element = elements.Element(nodes, ids) if type.GetDim() == dim - 1: mesh.AddSurfaceElement(element) elif type.GetDim() == dim: mesh.AddVolumeElement(element) else: debug.deprint("Warning: Element of type " + str(type) + " encountered in " + str(dim) + " dimensions") line = ReadNonCommentLine(fileHandle) assert(line == "$EndElements") # Ignore all remaining sections else: raise Exception("File type " + str(fileType) + " not recognised") fileHandle.close() if hasHalo: # Read the .halo file debug.dprint("Reading .halo file") if mesh_halos.HaloIOSupport(): halos = mesh_halos.ReadHalos(basename + ".halo") mesh.SetHalos(halos) else: debug.deprint("Warning: No .halo I/O support") return mesh