def WriteGid(mesh, filename):
  """
  Write a GiD file with the given filename
  """
  
  debug.dprint("Writing GiD mesh with filename " + filename)
  
  fileHandle = open(filename, "w")
  
  # Write the header
  fileHandle.write(utils.FormLine(["MESH", "dimension", mesh.GetDim(), "ElemType", "Unknown", "Nnode", mesh.VolumeElementFixedNodeCount()]))
  
  # Write the nodes
  fileHandle.write("Coordinates\n")
  for i, nodeCoord in enumerate(mesh.GetNodeCoords()):
    fileHandle.write("  " + utils.FormLine([i + 1, nodeCoord]))
  fileHandle.write("end coordinates\n")
  
  # Write the volume elements
  fileHandle.write("Elements\n")
  for i, element in enumerate(mesh.GetVolumeElements()):
    # Note: GiD file indexes nodes from 1, Mesh s index nodes from 0
    fileHandle.write("  " + utils.FormLine([i + 1, ToGidNodeOrder(utils.OffsetList(element.GetNodes(), 1), elements.ElementType(dim = mesh.GetDim(), nodeCount = element.NodeCount()))]))
  fileHandle.write("end elements\n")
  
  fileHandle.close()
  
  debug.dprint("Finished writing GiD mesh")
  
  return mesh
예제 #2
0
        def SItem(s, key, delimiter):
            if key in s:
                return s[key]
            else:
                keySplit = key.split(delimiter)
                for i in range(len(keySplit)):
                    key = utils.FormLine(keySplit[:i],
                                         delimiter=delimiter,
                                         newline=False)
                    if key in s:
                        if isinstance(s[key], dict):
                            try:
                                # Tolerate a failure when recursing, as the key may have been
                                # eroneously split
                                return SItem(
                                    s[key],
                                    utils.FormLine(keySplit[i:],
                                                   delimiter=delimiter,
                                                   newline=False), delimiter)
                            except Exception:
                                pass
                        else:
                            return s[key]

                raise Exception("Key not found")
def WriteHalos(halos, filename):
  """
  Write a Fluidity .halo file
  """
    
  xmlfile = xml.dom.minidom.Document()
  
  halosRootEle = xmlfile.createElement("halos")
  halosRootEle.setAttribute("process", str(halos.GetProcess()))
  halosRootEle.setAttribute("nprocs", str(halos.GetNProcesses()))
  xmlfile.appendChild(halosRootEle)
  
  halos = halos.LevelHaloDict()
  for level in halos.keys():
    halo = halos[level]
  
    haloEle = xmlfile.createElement("halo")
    haloEle.setAttribute("level", str(level))
    haloEle.setAttribute("n_private_nodes", str(halo.GetNOwnedNodes()))
    halosRootEle.appendChild(haloEle)
    
    for i, process in enumerate(range(halo.GetNProcesses())):
      haloDataEle = xmlfile.createElement("halo_data")
      haloDataEle.setAttribute("process", str(i))
      haloEle.appendChild(haloDataEle)
      
      sendEle = xmlfile.createElement("send")
      haloDataEle.appendChild(sendEle)
      
      if level > 0:
        sendText = xmlfile.createTextNode(utils.FormLine(utils.OffsetList(utils.ExpandList(halo.GetSends(process = i)), 1), delimiter = " ", newline = False))
      else:
        sendText = xmlfile.createTextNode(utils.FormLine(utils.ExpandList(halo.GetSends(process = i)), delimiter = " ", newline = False))
      sendEle.appendChild(sendText)
      
      receiveEle = xmlfile.createElement("receive")
      haloDataEle.appendChild(receiveEle)
      
      if level > 0:
        receiveText = xmlfile.createTextNode(utils.FormLine(utils.OffsetList(utils.ExpandList(halo.GetReceives(process = i)), 1), delimiter = " ", newline = False))
      else:
        receiveText = xmlfile.createTextNode(utils.FormLine(utils.ExpandList(halo.GetReceives(process = i)), delimiter = " ", newline = False))
      receiveEle.appendChild(receiveText)
  
  handle = open(filename, "w")
  if XmlExtSupport():
    xml.dom.ext.PrettyPrint(xmlfile, handle)
  else:
    xmlfile.writexml(handle)
  handle.flush()
  handle.close()
  
  return
예제 #4
0
def TetrahedralizePoly(polyFilename, commandLineSwitches=[]):
    """
  Tetrahedralise the given poly using TetGen
  """

    assert (filehandling.FileExtension(polyFilename) == ".poly")

    tempDir = tempfile.mkdtemp()
    tempFile = os.path.join(tempDir, os.path.basename(polyFilename))
    filehandling.Cp(polyFilename, tempFile)

    command = ["tetgen", "-p"]
    if debug.GetDebugLevel() > 1:
        command.append("-V")
        stdout = None
        stderr = None
    else:
        stdout = subprocess.PIPE
        stderr = subprocess.PIPE
    command += commandLineSwitches
    command.append(tempFile)
    debug.dprint("Tetrahedralization command: " +
                 utils.FormLine(command, delimiter=" ", newline=False))
    proc = subprocess.Popen(command, stdout=stdout, stderr=stderr)
    proc.wait()
    assert (proc.returncode == 0)

    mesh = triangletools.ReadTriangle(tempFile[:-5] + ".1")

    filehandling.Rmdir(tempDir, force=True)

    return mesh
예제 #5
0
def StripFileExtension(filename):
  """
  Strip the file extension from the supplied filename
  """

  split = os.path.basename(filename).split(".")
  
  if len(split) == 1:
    return filename
  else:
    return os.path.join(os.path.dirname(filename), utils.FormLine(split[:-1], delimiter = ".", newline = False))
예제 #6
0
def SplitVtuFilename(filename):
    """
  Split the supplied vtu filename into project, ID and file extension
  """

    first = filehandling.StripFileExtension(filename)
    ext = filehandling.FileExtension(filename)

    split = first.split("_") + [ext]

    idIndex = None
    for i, val in enumerate(split[1:]):
        if utils.IsIntString(val):
            idIndex = i + 1
            break
    assert (not idIndex is None)

    project = utils.FormLine(split[:idIndex], delimiter="_", newline=False)
    id = int(split[idIndex])
    ext = utils.FormLine([""] + split[idIndex + 1:len(split) - 1],
                         delimiter="_",
                         newline=False) + split[-1]

    return project, id, ext
예제 #7
0
def WriteTriangle(mesh, baseName):
  """
  Write triangle files with the given base name
  """
    
  def FileFooter():
    return "# Created by triangletools.WriteTriangle\n" + \
           "# Command: " + " ".join(sys.argv) + "\n" + \
           "# " + str(time.ctime()) + "\n"

  debug.dprint("Writing triangle mesh with base name " + baseName)
    
  # Write the .node file
  debug.dprint("Writing .node file")
  
  nodeHandle = open(baseName + ".node", "w")
  
  # Write the meta data
  nodeHandle.write(utils.FormLine([mesh.NodeCount(), mesh.GetDim(), 0, 0]))
  
  # Write the nodes
  for i in range(mesh.NodeCount()):
    nodeHandle.write(utils.FormLine([i + 1, mesh.GetNodeCoord(i)]))
  nodeHandle.write(FileFooter())
  nodeHandle.close()
    
  if mesh.GetDim() == 1:
    # Write the .bound file
    debug.dprint("Writing .bound file")
    
    boundHandle = open(baseName + ".bound", "w")
    
    # Write the meta data
    nBoundIds = 0
    for i in range(mesh.SurfaceElementCount()):
      if i == 0:
        nBoundIds = len(mesh.GetSurfaceElement(i).GetIds())
      else:
        assert(nBoundIds == len(mesh.GetSurfaceElement(i).GetIds()))
    boundHandle.write(utils.FormLine([mesh.SurfaceElementCount(), nBoundIds]))
    
    # Write the bounds
    for i in range(mesh.SurfaceElementCount()):
      boundHandle.write(utils.FormLine([i + 1, utils.OffsetList(mesh.GetSurfaceElement(i).GetNodes(), 1), mesh.GetSurfaceElement(i).GetIds()]))
    boundHandle.write(FileFooter())
    boundHandle.close()
  elif mesh.GetDim() == 2:
    # Write the .edge file
    debug.dprint("Writing .edge file")
    
    edgeHandle = open(baseName + ".edge", "w")
    
    # Write the meta data
    nEdgeIds = 0
    for i in range(mesh.SurfaceElementCount()):
      if i == 0:
        nEdgeIds = len(mesh.GetSurfaceElement(i).GetIds())
      else:
        assert(nEdgeIds == len(mesh.GetSurfaceElement(i).GetIds()))
    edgeHandle.write(utils.FormLine([mesh.SurfaceElementCount(), nEdgeIds]))
    
    # Write the edges
    for i in range(mesh.SurfaceElementCount()):
      edgeHandle.write(utils.FormLine([i + 1, utils.OffsetList(mesh.GetSurfaceElement(i).GetNodes(), 1), mesh.GetSurfaceElement(i).GetIds()]))
    edgeHandle.write(FileFooter())
    edgeHandle.close()
  elif mesh.GetDim() == 3:
    # Write the .face file
    debug.dprint("Writing .face file")
    
    faceHandle = open(baseName + ".face", "w")
    
    # Write the meta data
    nFaceIds = 0
    for i in range(mesh.SurfaceElementCount()):
      if i == 0:
        nFaceIds = len(mesh.GetSurfaceElement(i).GetIds())
      else:
        assert(nFaceIds == len(mesh.GetSurfaceElement(i).GetIds()))
    faceHandle.write(utils.FormLine([mesh.SurfaceElementCount(), nFaceIds]))
    
    # Write the faces
    for i in range(mesh.SurfaceElementCount()):
      faceHandle.write(utils.FormLine([i + 1, utils.OffsetList(mesh.GetSurfaceElement(i).GetNodes(), 1), mesh.GetSurfaceElement(i).GetIds()]))
    faceHandle.write(FileFooter())
    faceHandle.close()
    
  # Write the .ele file
  debug.dprint("Writing .ele file")
  
  eleHandle = open(baseName + ".ele", "w")
  
  # Write the meta data
  nNodesPerEle = 0
  nEleIds = 0
  for i in range(mesh.VolumeElementCount()):
    if i == 0:
      nEleIds = len(mesh.GetVolumeElement(i).GetIds())
      nNodesPerEle = mesh.GetVolumeElement(i).GetLoc()
    else:
      assert(nEleIds == len(mesh.GetVolumeElement(i).GetIds()))
      assert(nNodesPerEle == mesh.GetVolumeElement(i).GetLoc())
  eleHandle.write(utils.FormLine([mesh.VolumeElementCount(), nNodesPerEle, nEleIds]))
  
  # Write the eles
  for i in range(mesh.VolumeElementCount()):
    # Note: Triangle mesh indexes nodes from 1, Mesh s index nodes from 0
    eleHandle.write(utils.FormLine([i + 1, utils.OffsetList(mesh.GetVolumeElement(i).GetNodes(), 1), mesh.GetVolumeElement(i).GetIds()]))
  eleHandle.write(FileFooter())
  eleHandle.close()
  
  
  halos = mesh.GetHalos()
  if halos.HaloCount() > 0:
    # Write the .halo file
    debug.dprint("Writing .halo file")
    
    if mesh_halos.HaloIOSupport():
      mesh_halos.WriteHalos(halos, baseName + ".halo")
    else:
      debug.deprint("Warning: No .halo I/O support")

  debug.dprint("Finished writing triangle file")
    
  return
예제 #8
0
def WritePoly(mesh, filename, holeMesh=None):
    """
  Write a .poly file with the given base name
  """
    def FileFooter():
        return "# Created by WritePoly\n" + \
               "# Command: " + " ".join(sys.argv) + "\n" + \
               "# " + str(time.ctime()) + "\n"

    polyHandle = open(filename, "w")

    # Write the node meta data
    polyHandle.write("# Nodes\n")
    polyHandle.write(utils.FormLine([mesh.NodeCount(), mesh.GetDim(), 0, 0]))

    # Write the nodes
    for i in range(mesh.NodeCount()):
        polyHandle.write(utils.FormLine([i + 1, mesh.GetNodeCoord(i)]))

    # Write the facets meta data
    polyHandle.write("# Facets\n")
    nFacetIds = 0
    for i in range(mesh.SurfaceElementCount()):
        if i == 0:
            nFacetIds = len(mesh.GetSurfaceElement(i).GetIds())
        else:
            assert (nFacetIds == len(mesh.GetSurfaceElement(i).GetIds()))
    polyHandle.write(utils.FormLine([mesh.SurfaceElementCount(), nFacetIds]))

    # Write the facets
    if mesh.GetDim() == 2:
        # This is the facet specification as in the Triangle documentation
        # http://www.cs.cmu.edu/~quake/triangle.poly.html
        for i in range(mesh.SurfaceElementCount()):
            # Note: .poly indexes nodes from 1, Mesh s index nodes from 0
            polyHandle.write(
                utils.FormLine([
                    i + 1,
                    utils.OffsetList(mesh.GetSurfaceElement(i).GetNodes(), 1),
                    mesh.GetSurfaceElement(i).GetIds()
                ]))
    else:
        # This is the facet specification as in the Tetgen documentation
        # http://tetgen.berlios.de/fformats.poly.html
        for i in range(mesh.SurfaceElementCount()):
            polyHandle.write(
                utils.FormLine([1, 0, mesh.GetSurfaceElement(i).GetIds()]))
            # Note: .poly indexes nodes from 1, Mesh s index nodes from 0
            polyHandle.write(
                utils.FormLine([
                    mesh.GetSurfaceElement(i).NodeCount(),
                    utils.OffsetList(mesh.GetSurfaceElement(i).GetNodes(), 1)
                ]))

    # Write the hole list meta data
    polyHandle.write("# Holes\n")
    if holeMesh is None:
        polyHandle.write(utils.FormLine([0]))
    else:
        polyHandle.write(utils.FormLine([holeMesh.NodeCount()]))

        # Write the holes
        for i in range(holeMesh.NodeCount()):
            polyHandle.write(utils.FormLine([i + 1, holeMesh.GetNodeCoord(i)]))

    polyHandle.write(FileFooter())
    polyHandle.close()

    return
예제 #9
0
def WriteMsh(mesh, filename, binary = True):
  """
  Write a Gmsh msh file
  """
  
  if binary:
    # Binary format
    
    fileHandle = open(filename, "wb")
    
    # Write the MeshFormat section    
    fileHandle.write("$MeshFormat\n")
    version = 2.1
    fileType = 1
    dataSize = ctypes.sizeof(ctypes.c_double)
    fileHandle.write(utils.FormLine([version, fileType, dataSize]))
    
    iArr = array.array("i", [1])
    iArr.tofile(fileHandle)
    fileHandle.write("\n")
    
    fileHandle.write("$EndMeshFormat\n")
    
    # Write the Nodes section
    
    fileHandle.write("$Nodes\n")
    fileHandle.write(utils.FormLine([mesh.NodeCoordsCount()]))
    
    for i, nodeCoord in enumerate(mesh.GetNodeCoords()):
      nodeCoord = list(nodeCoord)
      while len(nodeCoord) < 3:
        nodeCoord.append(0.0)
      assert(len(nodeCoord) == 3)
      
      iArr = array.array("i", [i + 1])
      rArr = array.array("d", nodeCoord)
      iArr.tofile(fileHandle)
      rArr.tofile(fileHandle) 
    fileHandle.write("\n")     
    
    fileHandle.write("$EndNodes\n")
    
    # Write the Elements section
        
    fileHandle.write("$Elements\n")
    fileHandle.write(utils.FormLine([mesh.SurfaceElementCount() + mesh.VolumeElementCount()]))
    
    eleSort = {}
    for ele in mesh.GetSurfaceElements() + mesh.GetVolumeElements():
      eleType = ele.GetType()
      gmshType = GmshElementType(dim = eleType.GetDim(), nodeCount = eleType.GetNodeCount())
      
      key = (gmshType.GetGmshElementTypeId(), len(ele.GetIds()))
      if key in eleSort:
        eleSort[key].append(ele)
      else:
        eleSort[key] = [ele]
    
    index = 1
    for gmshEleId, nIds in eleSort:
      eles = eleSort[(gmshEleId, nIds)]
      iArr = array.array("i", [gmshEleId, len(eles), nIds])
      iArr.tofile(fileHandle)
      for ele in eles:
        iArr = array.array("i", [index] + list(ele.GetIds()) + utils.OffsetList(ToGmshNodeOrder(ele.GetNodes(), ele.GetType()), 1))
        iArr.tofile(fileHandle)
        index += 1
    assert(index == mesh.SurfaceElementCount() + mesh.VolumeElementCount() + 1)
    fileHandle.write("\n")
    
    fileHandle.write("$EndElements\n")
  else:
    # ASCII format
    
    fileHandle = open(filename, "w")
    
    # Write the MeshFormat section    
    fileHandle.write("$MeshFormat\n")
    version = 2.1
    fileType = 0
    dataSize = ctypes.sizeof(ctypes.c_double)
    fileHandle.write(utils.FormLine([version, fileType, dataSize]))    
    fileHandle.write("$EndMeshFormat\n")
    
    # Write the Nodes section
    
    fileHandle.write("$Nodes\n")
    fileHandle.write(utils.FormLine([mesh.NodeCoordsCount()]))
    for i, nodeCoord in enumerate(mesh.GetNodeCoords()):
      nodeCoord = list(nodeCoord)
      while len(nodeCoord) < 3:
        nodeCoord.append(0.0)
      assert(len(nodeCoord) == 3)
      fileHandle.write(utils.FormLine([i + 1, nodeCoord]))
    fileHandle.write("$EndNodes\n")
    
    # Write the Elements section
    
    fileHandle.write("$Elements\n")
    fileHandle.write(utils.FormLine([mesh.SurfaceElementCount() + mesh.VolumeElementCount()]))
    for i, ele in enumerate(mesh.GetSurfaceElements() + mesh.GetVolumeElements()):
      eleType = ele.GetType()
      gmshType = GmshElementType(dim = eleType.GetDim(), nodeCount = eleType.GetNodeCount())
      ids = ele.GetIds()
      fileHandle.write(utils.FormLine([i + 1, gmshType.GetGmshElementTypeId(), len(ids), ids, utils.OffsetList(ToGmshNodeOrder(ele.GetNodes(), eleType), 1)]))
    fileHandle.write("$EndElements\n")
  
  return
예제 #10
0
def DetectorArrays(stat):
    """
  Return a dictionary of detector array lists contained in the supplied stat
  """

    # Detector array data is divided in the stat into one path per array entry. We
    # want to collapse this into a dictionary of one path per array. This involves
    # lots of horrible parsing of stat paths.

    # Find all detector array names and the paths for each entry in the array
    arrays = {}  # The arrays
    notArrayNames = []  # List of candidate array names that are, in fact, not
    # detector array names
    for path in stat.PathLists():
        if isinstance(stat[stat.FormPathFromList(path)], Stat):
            # This isn't a leaf node
            continue

        # Look for an array marker in the path. This appears as:
        #   [path]%arrayname_index[%component]
        # and for coordinates as:
        #   arrayname_index[%component]

        if len(path) >= 2 and path[1] == "position":
            # This might be a coordinate entry

            firstKey = path[0]
            keySplit = firstKey.split("_")
            # We have an entry in an array if:
            #   1. We have more than one entry in the split
            #   2. The final entry in the split contains one of zero (for scalars) or
            #      two (for vector and tensors) array path delimiters
            #   3. The first stat path split of the final entry is an integer (the
            #      index)
            if len(keySplit) <= 1 \
              or not len(stat.SplitPath(keySplit[-1])) in [1, 2] \
              or not utils.IsIntString(stat.SplitPath(keySplit[-1])[0]):
                # This definitely can't be an entry in a detector array
                continue

            # OK, we have something that looks a bit like an entry for a detector
            # array

            # Find the array name and the index for this entry
            arrayName = utils.FormLine(
                [utils.FormLine(keySplit[:-1], delimiter="_", newline=False)] +
                path[1:],
                delimiter=stat.GetDelimiter(),
                newline=False)
            index = int(keySplit[-1])
        else:
            # This might be a field entry

            finalKey = path[-1]
            keySplit = finalKey.split("_")
            # We have an entry in an array if:
            #   1. We have more than one entry in the split
            #   2. The final entry in the split contains one of zero or one (for field
            #      components) array path delimiters
            #   3. The first stat path split of the final entry is an integer (the
            #      index)
            if len(keySplit) <= 1 \
              or not len(stat.SplitPath(keySplit[-1])) in [1, 2] \
              or not utils.IsIntString(stat.SplitPath(keySplit[-1])[0]):
                # This definitely can't be an entry in a detector array
                continue

            # OK, we have something that looks a bit like an entry for a detector
            # array

            # Find the array name and the index for this entry
            arrayName = utils.FormLine(
                path[:-1] +
                [utils.FormLine(keySplit[:-1], delimiter="_", newline=False)],
                delimiter=stat.GetDelimiter(),
                newline=False)
            if len(stat.SplitPath(keySplit[-1])) > 1:
                # This array name references a field component

                # We need to append the component to the array name. This needs to be
                # added to the last but one part of the stat path (the final entry is the
                # name of this detector array as configured in Fluidity).
                splitName = stat.SplitPath(arrayName)
                splitName[-2] = stat.FormPath(splitName[-2],
                                              stat.SplitPath(keySplit[-1])[1])
                arrayName = stat.FormPathFromList(splitName)
                index = int(stat.SplitPath(keySplit[-1])[0])
            else:
                # This array name references a field

                index = int(keySplit[-1])

        if arrayName in notArrayNames:
            # We've already discovered that this candidate array name isn't in fact a
            # detector array
            continue

        if index <= 0:
            # This isn't a valid index

            # This candidate array name isn't in fact a detector array
            notArrayNames.append(arrayName)
            if arrayName in arrays:
                arrays.remove(arrayName)
            continue
        if arrayName in arrays and index in arrays[arrayName]:
            # We've seen this index more than once for this array name

            # This candidate apparent array name isn't in fact a detector array
            notArrayNames.append(arrayName)
            arrays.remove(arrayName)
            continue

        if arrayName in arrays:
            arrays[arrayName][index] = stat[stat.FormPathFromList(path)]
        else:
            # This is a new array name
            arrays[arrayName] = {}
            arrays[arrayName][index] = stat[stat.FormPathFromList(path)]

    # Convert the dictionaries of data to lists, and check for consecutive
    # indices
    for name in arrays:
        array = arrays[name]
        indices = array.keys()
        data = [array[index] for index in indices]
        indices, data = utils.KeyedSort(indices, data, returnSortedKeys=True)
        arrays[name] = numpy.array(data)

        for i, index in enumerate(indices):
            if not i + 1 == index:
                # The indices are not consecutive from one. After all the hard work
                # above, we still have an array name that isn't in fact a detector
                # array.
                arrays.remove(name)
                break

    # Fantastic! We have our detectors dictionary!
    debug.dprint("Detector keys:")
    debug.dprint(arrays.keys())

    return arrays