Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
def VtuBoundingBox(vtu):
    """
  Return the bounding box of the supplied vtu
  """

    vtuBounds = vtu.ugrid.GetBounds()
    lbound, ubound = [vtuBounds[2 * i] for i in range(len(vtuBounds) / 2)], [
        vtuBounds[2 * i + 1] for i in range(len(vtuBounds) / 2)
    ]
    if len(lbound) > 0 and lbound[0] > ubound[0]:
        if optimise.DebuggingEnabled():
            for i in range(1, len(lbound)):
                assert (lbound[i] > ubound[i])
        lbound = [0.0 for i in range(len(lbound))]
        ubound = [0.0 for i in range(len(ubound))]

    return bounds.BoundingBox(lbound, ubound)
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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