def BoundingBox(self): lbound = [calc.Inf() for i in range(self.GetDim())] ubound = [-calc.Inf() for i in range(self.GetDim())] for nodeCoord in self.GetNodeCoords(): for i, val in enumerate(nodeCoord): if val < lbound[i]: lbound[i] = val if val > ubound[i]: ubound[i] = val return bounds.BoundingBox(lbound, ubound)
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
def ReadGid(filename): """ Read a GiD file with the given filename, and return it as a mesh """ debug.dprint("Reading GiD mesh with filename " + filename) fileHandle = open(filename, "r") # Read the header header = fileHandle.readline() lineSplit = header.split() assert(lineSplit[0] == "MESH") dimension = None elemType = None nnode = None for i, word in enumerate(lineSplit[:len(lineSplit) - 1]): if word == "dimension": dimension = int(lineSplit[i + 1]) assert(dimension >= 0) elif word == "ElemType": elemType = lineSplit[i + 1] elif word == "Nnode": nnode = int(lineSplit[i + 1]) assert(nnode >= 0) assert(not dimension is None) assert(not elemType is None) assert(not nnode is None) debug.dprint("Dimension = " + str(dimension)) debug.dprint("Element type = " + elemType) debug.dprint("Element nodes = " + str(nnode)) # Read the nodes nodeCoords = [] line = fileHandle.readline() index = 0 while len(line) > 0: if line.strip() == "Coordinates": line = fileHandle.readline() while not line.strip() == "end coordinates": assert(len(line) > 0) index += 1 lineSplit = line.split() assert(len(lineSplit) == 1 + dimension) assert(int(lineSplit[0]) == index) nodeCoords.append([float(coord) for coord in lineSplit[1:]]) line = fileHandle.readline() break line = fileHandle.readline() debug.dprint("Nodes: " + str(index)) # Check for unused dimensions lbound = [calc.Inf() for i in range(dimension)] ubound = [-calc.Inf() for i in range(dimension)] for nodeCoord in nodeCoords: for i, val in enumerate(nodeCoord): lbound[i] = min(lbound[i], val) ubound[i] = max(ubound[i], val) boundingBox = bounds.BoundingBox(lbound, ubound) actualDimension = boundingBox.UsedDim() if not dimension == actualDimension: debug.deprint("Dimension suggested by bounds = " + str(actualDimension)) debug.deprint("Warning: Header dimension inconsistent with bounds") dimension = actualDimension coordMask = boundingBox.UsedDimCoordMask() nodeCoords = [utils.MaskList(nodeCoord, coordMask) for nodeCoord in nodeCoords] mesh = meshes.Mesh(dimension) mesh.AddNodeCoords(nodeCoords) fileHandle.seek(0) # Read the volume elements line = fileHandle.readline() index = 0 while len(line) > 0: if line.strip() == "Elements": line = fileHandle.readline() while not line.strip() == "end elements": assert(len(line) > 0) index += 1 lineSplit = line.split() assert(len(lineSplit) == 1 + nnode) assert(int(lineSplit[0]) == index) # Note: GiD file indexes nodes from 1, Mesh s index nodes from 0 mesh.AddVolumeElement(elements.Element(nodes = FromGidNodeOrder([int(node) - 1 for node in lineSplit[1:]], elements.ElementType(dim = dimension, nodeCount = nnode)))) line = fileHandle.readline() break line = fileHandle.readline() debug.dprint("Elements: " + str(index)) fileHandle.close() debug.dprint("Finished reading GiD mesh") return mesh
def ReadAsciiMshV4(fileHandle): line = ReadNonCommentLine(fileHandle) assert (line == "$EndMeshFormat") # skip to the Nodes section while line != "$Nodes": line = ReadNonCommentLine(fileHandle) assert (line == "$Nodes") line = ReadNonCommentLine(fileHandle) lineSplit = line.split() numBlocks = int(lineSplit[0]) numNodes = int(lineSplit[1]) seenNode = [False] * numNodes nodeIds = [] nodes = [] lbound = [calc.Inf() for i in range(3)] ubound = [-calc.Inf() for i in range(3)] for b in range(numBlocks): line = ReadNonCommentLine(fileHandle) lineSplit = line.split() subNodes = int(lineSplit[3]) tagArr = [int(ReadNonCommentLine(fileHandle)) for i in range(subNodes)] for i in range(subNodes): line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert (len(lineSplit) == 3) nodeId = tagArr[i] coord = [float(comp) for comp in lineSplit] 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) lineSplit = line.split() numEntities = int(lineSplit[0]) numElems = int(lineSplit[1]) for i in range(numEntities): line = ReadNonCommentLine(fileHandle) lineSplit = line.split() entityDim = int(lineSplit[0]) entityTag = int(lineSplit[1]) elementType = int(lineSplit[2]) elemsInBlock = int(lineSplit[3]) type = GmshElementType(gmshElementTypeId=elementType) for j in range(elemsInBlock): line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert (len(lineSplit) == 1 + type.GetNodeCount()) ids = [entityTag, int(lineSplit[0])] nodes = FromGmshNodeOrder( [int(node) - 1 for node in lineSplit[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") line = ReadNonCommentLine(fileHandle) assert (line == "$EndElements") return mesh
def ReadAsciiMshV2(fileHandle): 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") return mesh
def ReadBinaryMshV4(fileHandle, dataSize): if dataSize == 4: sizeFormat = "i" elif dataSize == 8: sizeFormat = "l" else: raise Exception("Unrecognised size_t size " + str(dataSize)) swap = ByteSwap(fileHandle) line = ReadNonCommentLine(fileHandle) assert (line == "$EndMeshFormat") # skip ahead to Nodes section (possibly bypassing Entities) while line != "$Nodes": line = ReadNonCommentLine(fileHandle) assert (line == "$Nodes") # numEntityBlock(size_t) numNodes(size_t) # minNodeTag(size_t) maxNodeTag(size_t) # # entityDim(int) entityTag(int) parametric(int) numNodes(size_t) # # nodeTag(size_t) ... # x(double) y(double) z(double) ... # ... sArr = array.array(sizeFormat) sArr.fromfile(fileHandle, 4) if swap: sArr.byteswap() numBlocks = sArr[0] numNodes = sArr[1] # assume dense nodes (we can check using the min/max id fields) seenNode = [False] * numNodes nodeIds = [] nodes = [] lbound = [calc.Inf() for i in range(3)] ubound = [-calc.Inf() for i in range(3)] for b in range(numBlocks): iArr = array.array("i") sArr = array.array(sizeFormat) iArr.fromfile(fileHandle, 3) sArr.fromfile(fileHandle, 1) if swap: iArr.byteswap() sArr.byteswap() subNodes = sArr[0] tagArr = array.array(sizeFormat) tagArr.fromfile(fileHandle, subNodes) if swap: tagArr.byteswap() for i in range(subNodes): rArr = array.array("d") rArr.fromfile(fileHandle, 3) if swap: rArr.byteswap() nodeId = tagArr[i] 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") # numEntityBlocks(size_t) numElements(size_t) # minElementTag(size_t) maxElementTag(size_t) # # entityDim(int) entityTag(int) elementType(int) numElems(size_t) # elementTag(size_t) nodeTag(size_t) ... # ... # ... sArr = array.array(sizeFormat) sArr.fromfile(fileHandle, 4) if swap: sArr.byteswap() numEntities = sArr[0] numElems = sArr[1] for i in range(numEntities): iArr = array.array("i") sArr = array.array(sizeFormat) iArr.fromfile(fileHandle, 3) sArr.fromfile(fileHandle, 1) if swap: iArr.byteswap() sArr.byteswap() entityDim = iArr[0] entityTag = iArr[1] elementType = iArr[2] elemsInBlock = sArr[0] type = GmshElementType(gmshElementTypeId=elementType) for j in range(elemsInBlock): sArr = array.array(sizeFormat) sArr.fromfile(1 + type.GetNodeCount()) if swap: sArr.byteswap() ids = [entityTag, sArr[0]] nodes = FromGmshNodeOrder(utils.OffsetList(sArr[1:], -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") line = ReadNonCommentLine(fileHandle) assert (line == "$EndElements") return mesh
def ReadBinaryMshV2(fileHandle, dataSize): if dataSize == 4: realFormat = "f" elif dataSize == 8: realFormat = "d" else: raise Exception("Unrecognised real size " + str(dataSize)) swap = ByteSwap(fileHandle) line = ReadNonCommentLine(fileHandle) assert (line == "$EndMeshFormat") # Read the Nodes section (no PhysicalNames section in binary) line = ReadNonCommentLine(fileHandle) assert (line == "$Nodes") # number-of-nodes # node-number x-coord y-coord z-coord # ... 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") # number-of-elements # element-header-binary # element-binary # ... # where element-header-binary is: elm-type num-elm num-tags # where element-binary is: # num-elm * (4 + num-tags*4 + node-num*4) # node-num physical-tag elementary-tag node-nums ... 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") return mesh