def testPolyIo(self): tempDir = tempfile.mkdtemp() oldMesh = meshes.Mesh(2) oldMesh.AddNodeCoord([0.0, 0.0]) oldMesh.AddNodeCoord([1.0, 0.0]) oldMesh.AddNodeCoord([0.0, 1.0]) oldMesh.AddSurfaceElement(elements.Element(nodes=[0, 1])) oldMesh.AddSurfaceElement(elements.Element(nodes=[0, 2])) oldMesh.AddSurfaceElement(elements.Element(nodes=[1, 2])) oldHoleMesh = meshes.Mesh(2) oldHoleMesh.AddNodeCoord([0.1, 0.1]) oldHoleMesh.AddNodeCoord([0.2, 0.2]) filename = os.path.join(tempDir, "temp.poly") WritePoly(oldMesh, filename, holeMesh=oldHoleMesh) newMesh, newHoleMesh = ReadPoly(filename) self.assertEquals(oldHoleMesh.GetDim(), newHoleMesh.GetDim()) self.assertEquals(oldHoleMesh.NodeCount(), newHoleMesh.NodeCount()) self.assertEquals(oldHoleMesh.SurfaceElementCount(), newHoleMesh.SurfaceElementCount()) self.assertEquals(oldHoleMesh.VolumeElementCount(), newHoleMesh.VolumeElementCount()) self.assertEquals(oldHoleMesh.GetDim(), newHoleMesh.GetDim()) self.assertEquals(oldHoleMesh.NodeCount(), newHoleMesh.NodeCount()) self.assertEquals(oldHoleMesh.SurfaceElementCount(), newHoleMesh.SurfaceElementCount()) self.assertEquals(oldHoleMesh.VolumeElementCount(), newHoleMesh.VolumeElementCount()) oldMesh = meshes.Mesh(3) oldMesh.AddNodeCoord([0.0, 0.0, 0.0]) oldMesh.AddNodeCoord([1.0, 0.0, 0.0]) oldMesh.AddNodeCoord([0.0, 1.0, 0.0]) oldMesh.AddNodeCoord([0.0, 0.0, 1.0]) oldMesh.AddSurfaceElement(elements.Element(nodes=[0, 1, 2])) oldMesh.AddSurfaceElement(elements.Element(nodes=[0, 1, 3])) oldMesh.AddSurfaceElement(elements.Element(nodes=[0, 2, 3])) oldMesh.AddSurfaceElement(elements.Element(nodes=[1, 2, 3])) oldHoleMesh = meshes.Mesh(3) oldHoleMesh.AddNodeCoord([0.1, 0.1, 0.1]) oldHoleMesh.AddNodeCoord([0.2, 0.2, 0.2]) filename = os.path.join(tempDir, "temp.poly") WritePoly(oldMesh, filename, holeMesh=oldHoleMesh) newMesh, newHoleMesh = ReadPoly(filename) self.assertEquals(oldHoleMesh.GetDim(), newHoleMesh.GetDim()) self.assertEquals(oldHoleMesh.NodeCount(), newHoleMesh.NodeCount()) self.assertEquals(oldHoleMesh.SurfaceElementCount(), newHoleMesh.SurfaceElementCount()) self.assertEquals(oldHoleMesh.VolumeElementCount(), newHoleMesh.VolumeElementCount()) self.assertEquals(oldHoleMesh.GetDim(), newHoleMesh.GetDim()) self.assertEquals(oldHoleMesh.NodeCount(), newHoleMesh.NodeCount()) self.assertEquals(oldHoleMesh.SurfaceElementCount(), newHoleMesh.SurfaceElementCount()) self.assertEquals(oldHoleMesh.VolumeElementCount(), newHoleMesh.VolumeElementCount()) filehandling.Rmdir(tempDir, force=True) return
def Mesh(self, quadMesh=False): mesh = meshes.Mesh(2) yxToNode = [] index = 0 for yCoord in self.YCoords(): yxToNode.append([]) for xCoord in self.XCoords(): mesh.AddNodeCoord([xCoord, yCoord]) yxToNode[-1].append(index) index += 1 for i in range(self.XCoordsCount())[:-1]: for j in range(self.YCoordsCount())[:-1]: if quadMesh: mesh.AddVolumeElement( elements.Element([ yxToNode[j + 1][i], yxToNode[j + 1][i + 1], yxToNode[j][i], yxToNode[j][i + 1] ])) else: # Default to triangle mesh, as quad quadrature is currently broken in # Fluidity mesh.AddVolumeElement( elements.Element([ yxToNode[j][i], yxToNode[j + 1][i], yxToNode[j][i + 1] ])) mesh.AddVolumeElement( elements.Element([ yxToNode[j + 1][i], yxToNode[j + 1][i + 1], yxToNode[j][i + 1] ])) return mesh
def testMshIo(self): tempDir = tempfile.mkdtemp() oldMesh = meshes.Mesh(2) oldMesh.AddNodeCoord([0.0, 0.0]) oldMesh.AddNodeCoord([1.0, 0.0]) oldMesh.AddNodeCoord([0.0, 1.0]) oldMesh.AddVolumeElement(elements.Element(nodes=[0, 1, 2])) oldMesh.AddSurfaceElement(elements.Element(nodes=[0, 1])) oldMesh.AddSurfaceElement(elements.Element(nodes=[0, 2])) oldMesh.AddSurfaceElement(elements.Element(nodes=[1, 2])) filename = os.path.join(tempDir, "temp") WriteMsh(oldMesh, filename, binary=False) newMesh = ReadMsh(filename) filehandling.Rmdir(tempDir, force=True) self.assertEquals(oldMesh.GetDim(), newMesh.GetDim()) self.assertEquals(oldMesh.NodeCount(), newMesh.NodeCount()) self.assertEquals(oldMesh.SurfaceElementCount(), newMesh.SurfaceElementCount()) self.assertEquals(oldMesh.VolumeElementCount(), newMesh.VolumeElementCount()) tempDir = tempfile.mkdtemp() oldMesh = meshes.Mesh(2) oldMesh.AddNodeCoord([0.0, 0.0]) oldMesh.AddNodeCoord([1.0, 0.0]) oldMesh.AddNodeCoord([0.0, 1.0]) oldMesh.AddVolumeElement(elements.Element(nodes=[0, 1, 2])) oldMesh.AddSurfaceElement(elements.Element(nodes=[0, 1])) oldMesh.AddSurfaceElement(elements.Element(nodes=[0, 2])) oldMesh.AddSurfaceElement(elements.Element(nodes=[1, 2])) filename = os.path.join(tempDir, "temp") WriteMsh(oldMesh, filename, binary=True) newMesh = ReadMsh(filename) filehandling.Rmdir(tempDir, force=True) self.assertEquals(oldMesh.GetDim(), newMesh.GetDim()) self.assertEquals(oldMesh.NodeCount(), newMesh.NodeCount()) self.assertEquals(oldMesh.SurfaceElementCount(), newMesh.SurfaceElementCount()) self.assertEquals(oldMesh.VolumeElementCount(), newMesh.VolumeElementCount()) return
def testTriangulatePoly(self): tempDir = tempfile.mkdtemp() mesh = meshes.Mesh(2) mesh.AddNodeCoords([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [0.1, 0.1]]) mesh.AddSurfaceElement(elements.Element([0, 1])) mesh.AddSurfaceElement(elements.Element([1, 2])) mesh.AddSurfaceElement(elements.Element([2, 0])) filename = os.path.join(tempDir, "test.poly") WritePoly(mesh, filename) mesh = TriangulatePoly(filename, commandLineSwitches=["-YY"]) self.assertEquals(mesh.NodeCount(), 4) self.assertEquals(mesh.VolumeElementCount(), 3) self.assertEquals(mesh.SurfaceElementCount(), 0) filehandling.Rmdir(tempDir, force=True) return
def ReadPoly(filename): """ Read a .poly file, and return is as two meshes: the poly mesh, and the hole nodes. Facet information is flattened, to create a single mesh surface. """ 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 fileHandle = open(filename, "r") # Read the nodes meta data line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert (len(lineSplit) == 4) nodeCount = int(lineSplit[0]) assert (nodeCount >= 0) dim = int(lineSplit[1]) assert (dim >= 0) nNodeAttributes = int(lineSplit[2]) assert (nNodeAttributes >= 0) nNodeIds = int(lineSplit[3]) assert (nNodeIds >= 0) mesh = meshes.Mesh(dim) holeMesh = meshes.Mesh(dim) # Read the nodes for i in range(nodeCount): line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert (len(lineSplit) == 1 + dim + nNodeAttributes + nNodeIds) assert (int(lineSplit[0]) == i + 1) mesh.AddNodeCoord([float(coord) for coord in lineSplit[1:1 + dim]]) # Read the facets meta data line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert (len(lineSplit) == 2) nFacets = int(lineSplit[0]) assert (nFacets >= 0) nIds = int(lineSplit[1]) assert (nIds >= 0) # Read the facets if dim == 2: # This is the facet specification as in the Triangle documentation # http://www.cs.cmu.edu/~quake/triangle.poly.html for i in range(nFacets): line = ReadNonCommentLine(fileHandle) lineSplit = line.split() nodeCount = 2 assert (len(lineSplit) == 1 + nodeCount + nIds) # Note: .poly indexes nodes from 1, Mesh s index nodes from 0 mesh.AddSurfaceElement( elements.Element(nodes=[ int(node) - 1 for node in lineSplit[1:1 + nodeCount] ], ids=[int(id) for id in lineSplit[-nIds:]])) else: # This is the facet specification as in the Tetgen documentation # http://tetgen.berlios.de/fformats.poly.html for i in range(nFacets): line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert (len(lineSplit) in range(2 + nIds + 1)) nSurfaceElements = int(lineSplit[0]) if len(lineSplit) > 1: nHoles = int(lineSplit[1]) ids = [int(id) for id in lineSplit[2:]] for i in range(nSurfaceElements): line = ReadNonCommentLine(fileHandle) lineSplit = line.split() nodeCount = int(lineSplit[0]) assert (len(lineSplit) == 1 + nodeCount) # Note: .poly indexes nodes from 1, Mesh s index nodes from 0 mesh.AddSurfaceElement( elements.Element( nodes=[int(node) - 1 for node in lineSplit[1:]], ids=copy.deepcopy(ids))) # Not sure how to deal with this assert (nHoles == 0) # Read the holes meta data line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert (len(lineSplit) == 1) holeNodeCount = int(lineSplit[0]) assert (holeNodeCount >= 0) # Read the holes for i in range(holeNodeCount): line = ReadNonCommentLine(fileHandle) lineSplit = line.split() assert (len(lineSplit) == 1 + dim) assert (int(lineSplit[0]) == i + 1) holeMesh.AddNodeCoord([float(coord) for coord in lineSplit[1:1 + dim]]) # Read the region attributes line = ReadNonCommentLine(fileHandle) if len(line) > 0: lineSplit = line.split() assert (len(lineSplit) == 1) nRegions = int(lineSplit[0]) # Not sure how to deal with this assert (nRegions == 0) fileHandle.close() return mesh, holeMesh
def GenerateCuboidMesh(xCoords, yCoords, zCoords, leftId=1, rightId=2, topId=3, bottomId=4, frontId=5, backId=6, volumeId=0): """ Generate a structured cuboid mesh """ debug.dprint("Generating cuboid mesh") mesh = meshes.Mesh(3) nXCoords = len(xCoords) nYCoords = len(yCoords) nZCoords = len(zCoords) # Copy and sort the input coords lXCoords = copy.deepcopy(xCoords) lYCoords = copy.deepcopy(yCoords) lZCoords = copy.deepcopy(zCoords) lXCoords.sort() lYCoords.sort() lZCoords.sort() # Generate map from x, y, z IDs to node IDs xyzToNode = [] index = 0 for i in range(nXCoords): xyzToNode.append([]) for j in range(nYCoords): xyzToNode[-1].append([index + i for i in range(nZCoords)]) index += nZCoords # Generate node coordinates for x in lXCoords: for y in lYCoords: for z in lZCoords: mesh.AddNodeCoord([x, y, z]) # Generate volume elements for i in range(nXCoords - 1): debug.dprint( "Processing x element strip " + str(i + 1) + " of " + str(nXCoords - 1), 2) for j in range(nYCoords - 1): debug.dprint( "Processing y element strip " + str(i + 1) + " of " + str(nYCoords - 1), 3) for k in range(nZCoords - 1): # Out of a hex, construct 6 tets # Construction as in IEEE Transactions on Magnetics, Vol. 26, # No. 2 March 1990 pp. 775-778, Y Tanizume, H Yamashita and # E Nakamae, Fig. 5. a) # Tet 1 mesh.AddVolumeElement( elements.Element([ xyzToNode[i + 1][j][k], xyzToNode[i][j][k], xyzToNode[i][j][k + 1], xyzToNode[i + 1][j + 1][k] ], volumeId)) # Tet 2 mesh.AddVolumeElement( elements.Element([ xyzToNode[i + 1][j][k], xyzToNode[i + 1][j][k + 1], xyzToNode[i + 1][j + 1][k], xyzToNode[i][j][k + 1] ], volumeId)) # Tet 3 mesh.AddVolumeElement( elements.Element([ xyzToNode[i + 1][j][k + 1], xyzToNode[i + 1][j + 1][k + 1], xyzToNode[i + 1][j + 1][k], xyzToNode[i][j][k + 1] ], volumeId)) # Tet 4 mesh.AddVolumeElement( elements.Element([ xyzToNode[i][j][k + 1], xyzToNode[i + 1][j + 1][k], xyzToNode[i][j + 1][k + 1], xyzToNode[i + 1][j + 1][k + 1] ], volumeId)) # Tet 5 mesh.AddVolumeElement( elements.Element([ xyzToNode[i][j][k + 1], xyzToNode[i + 1][j + 1][k], xyzToNode[i][j + 1][k], xyzToNode[i][j + 1][k + 1] ], volumeId)) # Tet 6 mesh.AddVolumeElement( elements.Element([ xyzToNode[i][j][k], xyzToNode[i + 1][j + 1][k], xyzToNode[i][j + 1][k], xyzToNode[i][j][k + 1] ], volumeId)) # Generate surface elements ... # ... for left for i in range(nYCoords - 1): for j in range(nZCoords - 1): mesh.AddSurfaceElement( elements.Element([ xyzToNode[0][i][j], xyzToNode[0][i][j + 1], xyzToNode[0][i + 1][j] ], leftId)) mesh.AddSurfaceElement( elements.Element([ xyzToNode[0][i][j + 1], xyzToNode[0][i + 1][j + 1], xyzToNode[0][i + 1][j] ], leftId)) # ... for right for i in range(nYCoords - 1): for j in range(nZCoords - 1): mesh.AddSurfaceElement( elements.Element([ xyzToNode[-1][i][j], xyzToNode[-1][i][j + 1], xyzToNode[-1][i + 1][j] ], rightId)) mesh.AddSurfaceElement( elements.Element([ xyzToNode[-1][i][j + 1], xyzToNode[-1][i + 1][j + 1], xyzToNode[-1][i + 1][j] ], rightId)) # ... for front for i in range(nXCoords - 1): for j in range(nZCoords - 1): mesh.AddSurfaceElement( elements.Element([ xyzToNode[i][0][j], xyzToNode[i + 1][0][j], xyzToNode[i][0][j + 1] ], frontId)) mesh.AddSurfaceElement( elements.Element([ xyzToNode[i][0][j + 1], xyzToNode[i + 1][0][j], xyzToNode[i + 1][0][j + 1] ], frontId)) # ... for back for i in range(nXCoords - 1): for j in range(nZCoords - 1): mesh.AddSurfaceElement( elements.Element([ xyzToNode[i][-1][j], xyzToNode[i + 1][-1][j], xyzToNode[i][-1][j + 1] ], backId)) mesh.AddSurfaceElement( elements.Element([ xyzToNode[i][-1][j + 1], xyzToNode[i + 1][-1][j], xyzToNode[i + 1][-1][j + 1] ], backId)) # ... for bottom for i in range(nXCoords - 1): for j in range(nYCoords - 1): mesh.AddSurfaceElement( elements.Element([ xyzToNode[i][j][0], xyzToNode[i + 1][j][0], xyzToNode[i + 1][j + 1][0] ], bottomId)) mesh.AddSurfaceElement( elements.Element([ xyzToNode[i][j][0], xyzToNode[i][j + 1][0], xyzToNode[i + 1][j + 1][0] ], bottomId)) # ... for top for i in range(nXCoords - 1): for j in range(nYCoords - 1): mesh.AddSurfaceElement( elements.Element([ xyzToNode[i][j][-1], xyzToNode[i + 1][j][-1], xyzToNode[i + 1][j + 1][-1] ], topId)) mesh.AddSurfaceElement( elements.Element([ xyzToNode[i][j][-1], xyzToNode[i][j + 1][-1], xyzToNode[i + 1][j + 1][-1] ], topId)) debug.dprint("Finished generating cuboid mesh") return mesh
def GenerateRectangleMesh(xCoords, yCoords, leftId=1, rightId=2, topId=3, bottomId=4, volumeId=0, elementFamilyId=elements.ELEMENT_FAMILY_SIMPLEX): """ Generate a structured 2D linear tet rectangular mesh based upon the given x and y coordinates """ debug.dprint("Generating rectangle mesh") nXCoords = len(xCoords) nYCoords = len(yCoords) # Copy and sort the input coords lXCoords = copy.deepcopy(xCoords) lYCoords = copy.deepcopy(yCoords) lXCoords.sort() lYCoords.sort() # Generate map from x, y IDs to node IDs xyToNode = [] index = 0 for i in range(nXCoords): xyToNode.append([index + i for i in range(nYCoords)]) index += nYCoords mesh = meshes.Mesh(2) # Generate node coordinates for x in lXCoords: for y in lYCoords: mesh.AddNodeCoord([x, y]) if elementFamilyId == elements.ELEMENT_FAMILY_SIMPLEX: # Generate volume elements for i in range(nXCoords - 1): debug.dprint( "Processing x element strip " + str(i + 1) + " of " + str(nXCoords - 1), 2) for j in range(nYCoords - 1): debug.dprint( "Processing y element strip " + str(i + 1) + " of " + str(nYCoords - 1), 3) # Out of a quad, construct 2 triangles # Triangle 1 mesh.AddVolumeElement( elements.Element([ xyToNode[i][j], xyToNode[i + 1][j], xyToNode[i + 1][j + 1] ], volumeId)) # Triangle 2 mesh.AddVolumeElement( elements.Element([ xyToNode[i][j], xyToNode[i + 1][j + 1], xyToNode[i][j + 1] ], volumeId)) elif elementFamilyId == elements.ELEMENT_FAMILY_CUBIC: # Generate volume elements for i in range(nXCoords - 1): debug.dprint( "Processing x element strip " + str(i + 1) + " of " + str(nXCoords - 1), 2) for j in range(nYCoords - 1): debug.dprint( "Processing y element strip " + str(i + 1) + " of " + str(nYCoords - 1), 3) # Quad mesh.AddVolumeElement( elements.Element([ xyToNode[i][j], xyToNode[i + 1][j], xyToNode[i][j + 1], xyToNode[i + 1][j + 1] ], volumeId)) else: raise Exception("Unsupported element family") # Generate surface elements... # ... for left for i in range(nYCoords - 1): mesh.AddSurfaceElement( elements.Element([xyToNode[0][i], xyToNode[0][i + 1]], leftId)) # ... for right for i in range(nYCoords - 1): mesh.AddSurfaceElement( elements.Element([xyToNode[-1][i], xyToNode[-1][i + 1]], rightId)) # ... for bottom for i in range(nXCoords - 1): mesh.AddSurfaceElement( elements.Element([xyToNode[i][0], xyToNode[i + 1][0]], bottomId)) # ... for top for i in range(nXCoords - 1): mesh.AddSurfaceElement( elements.Element([xyToNode[i][-1], xyToNode[i + 1][-1]], topId)) debug.dprint("Finished generating rectangle mesh") return mesh
def GenerateAnnulusHorizontalSliceMesh(rCoords, phiCoords, innerWallId=1, outerWallId=2, leftWallId=5, rightWallId=6, volumeId=0, connectEnds=True): """ Generate a horizontal annulus slice mesh """ debug.dprint("Generating annulus horizonal slice mesh") if connectEnds: debug.dprint("Annulus is connected") else: debug.dprint("Annulus is blocked") # Copy and sort the input coords lRCoords = copy.deepcopy(rCoords) lPhiCoords = copy.deepcopy(phiCoords) lRCoords.sort() lPhiCoords = [] for phi in phiCoords: while phi < 0.0: phi += 2.0 * math.pi while phi > 2.0 * math.pi: phi -= 2.0 * math.pi lPhiCoords.append(phi) lPhiCoords.sort() phiPoints = len(lPhiCoords) if connectEnds: phiDivisions = phiPoints else: phiDivisions = phiPoints - 1 nRCoords = len(rCoords) # Generate map from r, phi IDs to node IDs rPhiToNode = [] index = 0 for i in range(nRCoords): rPhiToNode.append([]) for j in range(phiPoints): rPhiToNode[i].append(index) index += 1 mesh = meshes.Mesh(2) # Generate node coordinates for r in lRCoords: for phi in lPhiCoords: x = r * math.cos(phi) y = r * math.sin(phi) mesh.AddNodeCoord([x, y]) # Generate volume elements for i in range(nRCoords - 1): debug.dprint( "Processing radial element strip " + str(i + 1) + " of " + str(nRCoords - 1), 2) for j in range(phiDivisions): mesh.AddVolumeElement( elements.Element([ rPhiToNode[i][j], rPhiToNode[i + 1][j], rPhiToNode[i][(j + 1) % phiPoints] ], volumeId)) mesh.AddVolumeElement( elements.Element([ rPhiToNode[i + 1][(j + 1) % phiPoints], rPhiToNode[i + 1][j], rPhiToNode[i][(j + 1) % phiPoints] ], volumeId)) # Generate surface elements ... # ... for inner wall for i in range(phiDivisions): mesh.AddSurfaceElement( elements.Element( [rPhiToNode[0][i], rPhiToNode[0][(i + 1) % phiPoints]], innerWallId)) # ... for outer wall for i in range(phiDivisions): mesh.AddSurfaceElement( elements.Element( [rPhiToNode[-1][i], rPhiToNode[-1][(i + 1) % phiPoints]], outerWallId)) if not connectEnds: # ... for left wall for i in range(nRCoords - 1): mesh.AddSurfaceElement( elements.Element([rPhiToNode[i][0], rPhiToNode[i + 1][0]], leftWallId)) # ... for right wall for i in range(nRCoords - 1): mesh.AddSurfaceElement( elements.Element([rPhiToNode[i][-1], rPhiToNode[i + 1][-1]], rightWallId)) debug.dprint("Finished generating annulus horizontal slice mesh") 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 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
sys.exit(0) if len(args) < 2: debug.FatalError("Number of nodes and number of meshes required") try: nodeCount = int(args[0]) assert(nodeCount >= 0) except [ValueError, AssertionError]: debug.FatalError("Number of nodes must be a positive integer") try: meshCount = int(args[1]) assert(meshCount >= 0) except [ValueError, AssertionError]: debug.FatalError("Number of meshes must be a positive integer") baseMesh = meshes.Mesh(2) baseMesh.AddNodeCoords(([0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0])) baseMesh.AddSurfaceElement(elements.Element([0, 1], ids = [1])) baseMesh.AddSurfaceElement(elements.Element([1, 3], ids = [2])) baseMesh.AddSurfaceElement(elements.Element([3, 2], ids = [3])) baseMesh.AddSurfaceElement(elements.Element([2, 0], ids = [4])) tempDir = tempfile.mkdtemp() for i in range(meshCount): mesh = copy.deepcopy(baseMesh) mesh.AddNodeCoords([[random.random(), random.random()] for j in range(nodeCount)]) polyFilename = os.path.join(tempDir, str(i) + ".poly") polytools.WritePoly(mesh, polyFilename) mesh = polytools.TriangulatePoly(polyFilename, commandLineSwitches = ["-YY"]) gmshtools.WriteMsh(mesh, str(i))
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
if len(argv) > 7: Ox = float(argv[7]) Oy = float(argv[8]) Oz = float(argv[9]) else: Ox = 0.0 Oy = 0.0 Oz = 0.0 nodes = Nx * Ny * Nz dx = Lx / (Nx - 1) dy = Ly / (Ny - 1) dz = Lz / (Nz - 1) # We're building a 3D mesh mesh = meshes.Mesh(3) ### ### Add node coordinates for i in range(nodes): zlayer = i / (Nx * Ny) j = i - zlayer * (Nx * Ny) ylayer = j / Nx xlayer = j - ylayer * Nx x = Ox + xlayer * dx y = Oy + ylayer * dy z = Oz + zlayer * dz column = j + 1 mesh.AddNodeCoord([x, y, z]) ###
def GenerateAnnulusMesh(rCoords, zCoords, phiCoords, innerWallId=1, outerWallId=2, topId=3, bottomId=4, leftWallId=5, rightWallId=6, volumeId=0, connectEnds=True): """ Generate a structured 3D linear tet annulus mesh based upon the given r and z phi coordinates """ debug.dprint("Generating annulus mesh") if connectEnds: debug.dprint("Annulus is connected") else: debug.dprint("Annulus is blocked") # Copy and sort the input coords lRCoords = copy.deepcopy(rCoords) lZCoords = copy.deepcopy(zCoords) lPhiCoords = copy.deepcopy(phiCoords) lRCoords.sort() lZCoords.sort() lPhiCoords = [] for phi in phiCoords: while phi < 0.0: phi += 2.0 * math.pi while phi > 2.0 * math.pi: phi -= 2.0 * math.pi lPhiCoords.append(phi) lPhiCoords.sort() phiPoints = len(lPhiCoords) if connectEnds: phiDivisions = phiPoints else: phiDivisions = phiPoints - 1 nRCoords = len(rCoords) nZCoords = len(zCoords) # Generate map from r, z, phi IDs to node IDs rzphiToNode = GenerateAnnulusRZPhiToNode(nRCoords, nZCoords, phiPoints) mesh = meshes.Mesh(3) # Generate node coordinates for r in lRCoords: for z in lZCoords: for phi in lPhiCoords: x = r * math.cos(phi) y = r * math.sin(phi) mesh.AddNodeCoord([x, y, z]) # Generate volume elements for i in range(nRCoords - 1): debug.dprint( "Processing radial element strip " + str(i + 1) + " of " + str(nRCoords - 1), 2) for j in range(nZCoords - 1): debug.dprint( "Processing vertical element loop " + str(j + 1) + " of " + str(nZCoords - 1), 3) for k in range(phiDivisions): # Out of a hex, construct 6 tets # Construction as in IEEE Transactions on Magnetics, Vol. 26, # No. 2 March 1990 pp. 775-778, Y Tanizume, H Yamashita and # E Nakamae, Fig. 5. a) # Tet 1 mesh.AddVolumeElement( elements.Element([ rzphiToNode[i + 1][j][k], rzphiToNode[i][j][k], rzphiToNode[i + 1][j + 1][k], rzphiToNode[i][j][(k + 1) % phiPoints] ], volumeId)) # Tet 2 mesh.AddVolumeElement( elements.Element([ rzphiToNode[i + 1][j][k], rzphiToNode[i + 1][j][(k + 1) % phiPoints], rzphiToNode[i][j][(k + 1) % phiPoints], rzphiToNode[i + 1][j + 1][k] ], volumeId)) # Tet 3 mesh.AddVolumeElement( elements.Element([ rzphiToNode[i + 1][j][(k + 1) % phiPoints], rzphiToNode[i + 1][j + 1][(k + 1) % phiPoints], rzphiToNode[i][j][(k + 1) % phiPoints], rzphiToNode[i + 1][j + 1][k] ], volumeId)) # Tet 4 mesh.AddVolumeElement( elements.Element([ rzphiToNode[i][j][(k + 1) % phiPoints], rzphiToNode[i + 1][j + 1][k], rzphiToNode[i + 1][j + 1][(k + 1) % phiPoints], rzphiToNode[i][j + 1][(k + 1) % phiPoints] ], volumeId)) # Tet 5 mesh.AddVolumeElement( elements.Element([ rzphiToNode[i][j][(k + 1) % phiPoints], rzphiToNode[i + 1][j + 1][k], rzphiToNode[i][j + 1][(k + 1) % phiPoints], rzphiToNode[i][j + 1][k] ], volumeId)) # Tet 6 mesh.AddVolumeElement( elements.Element([ rzphiToNode[i][j][k], rzphiToNode[i + 1][j + 1][k], rzphiToNode[i][j][(k + 1) % phiPoints], rzphiToNode[i][j + 1][k] ], volumeId)) # Generate surface elements ... # ... for inner wall for i in range(nZCoords - 1): for j in range(phiDivisions): mesh.AddSurfaceElement( elements.Element([ rzphiToNode[0][i][j], rzphiToNode[0][i][(j + 1) % phiPoints], rzphiToNode[0][i + 1][j] ], innerWallId)) mesh.AddSurfaceElement( elements.Element([ rzphiToNode[0][i][(j + 1) % phiPoints], rzphiToNode[0][i + 1][(j + 1) % phiPoints], rzphiToNode[0][i + 1][j] ], innerWallId)) # ... for outer wall for i in range(nZCoords - 1): for j in range(phiDivisions): mesh.AddSurfaceElement( elements.Element([ rzphiToNode[-1][i][j], rzphiToNode[-1][i][(j + 1) % phiPoints], rzphiToNode[-1][i + 1][j] ], outerWallId)) mesh.AddSurfaceElement( elements.Element([ rzphiToNode[-1][i][(j + 1) % phiPoints], rzphiToNode[-1][i + 1][(j + 1) % phiPoints], rzphiToNode[-1][i + 1][j] ], outerWallId)) # ... for top for i in range(nRCoords - 1): for j in range(phiDivisions): mesh.AddSurfaceElement( elements.Element([ rzphiToNode[i][-1][j], rzphiToNode[i + 1][-1][j], rzphiToNode[i][-1][(j + 1) % phiPoints] ], topId)) mesh.AddSurfaceElement( elements.Element([ rzphiToNode[i][-1][(j + 1) % phiPoints], rzphiToNode[i + 1][-1][j], rzphiToNode[i + 1][-1][(j + 1) % phiPoints] ], topId)) # ... for bottom for i in range(nRCoords - 1): for j in range(phiDivisions): mesh.AddSurfaceElement( elements.Element([ rzphiToNode[i][0][j], rzphiToNode[i + 1][0][j], rzphiToNode[i][0][(j + 1) % phiPoints] ], bottomId)) mesh.AddSurfaceElement( elements.Element([ rzphiToNode[i][0][(j + 1) % phiPoints], rzphiToNode[i + 1][0][j], rzphiToNode[i + 1][0][(j + 1) % phiPoints] ], bottomId)) if not connectEnds: # ... for left wall for i in range(nRCoords - 1): for j in range(nZCoords - 1): mesh.AddSurfaceElement( elements.Element([ rzphiToNode[i][j][0], rzphiToNode[i + 1][j][0], rzphiToNode[i + 1][j + 1][0] ], leftWallId)) mesh.AddSurfaceElement( elements.Element([ rzphiToNode[i][j][0], rzphiToNode[i][j + 1][0], rzphiToNode[i + 1][j + 1][0] ], leftWallId)) # ... for right wall for i in range(nRCoords - 1): for j in range(nZCoords - 1): mesh.AddSurfaceElement( elements.Element([ rzphiToNode[i][j][-1], rzphiToNode[i + 1][j][-1], rzphiToNode[i + 1][j + 1][-1] ], rightWallId)) mesh.AddSurfaceElement( elements.Element([ rzphiToNode[i][j][-1], rzphiToNode[i][j + 1][-1], rzphiToNode[i + 1][j + 1][-1] ], rightWallId)) debug.dprint("Finished generating annulus mesh") 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 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