예제 #1
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
예제 #2
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
 def LinearlyInterpolate(self, x, y):
   """
   Probe the slice data at the supplied coordinate, by linearly interpolating
   from the surrounding data points.
   """
   
   assert(self.XCoordsCount() > 0 and self.YCoordsCount() > 0)
   assert(x >= self.XCoord(0) and x <= self.XCoord(-1))
   assert(y >= self.YCoord(0) and y < self.YCoord(-1))
   
   # Peform a binary search for the left index
   left = calc.IndexBinaryLboundSearch(x, self.XCoords())
       
   # Perform  a binary search for the lower index
   lower = calc.IndexBinaryLboundSearch(y, self.YCoords())
   
   if self.XCoordsCount() > 1:
     right = left + 1
   else:
     # This is slightly inefficient (could avoid a linear interpolation if we
     # wanted)
     right = left
     
   if self.YCoordsCount() > 1:
     upper = lower + 1
   else:
     # This is slightly inefficient (could avoid a linear interpolation if we
     # wanted)
     upper = lower
   
   debug.dprint("left = " + str(left), 3)
   debug.dprint("lower = " + str(lower), 3)
     
   return calc.BilinearlyInterpolate(self.GetVal(left, upper), self.GetVal(right, upper), self.GetVal(left, lower), self.GetVal(right, lower), \
     (x - self.XCoord(left)) / (self.XCoord(right) - self.XCoord(left)), (y - self.YCoord(lower)) / (self.YCoord(upper) - self.YCoord(lower)))
예제 #4
0
def FluidityBinary(
        binaries=[
            "dfluidity-debug", "dfluidity", "fluidity-debug", "fluidity"
        ]):
    """
  Return the command used to call Fluidity
  """

    binary = None

    for possibleBinary in binaries:
        process = subprocess.Popen(["which", possibleBinary],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        process.wait()
        if process.returncode == 0:
            binary = possibleBinary
            debug.dprint("Fluidity binary: " +
                         str(process.stdout.readlines()[0]),
                         newline=False)
            break

    if binary is None:
        raise Exception("Failed to find Fluidity binary")

    return binary
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
예제 #6
0
def EnableDebugging():
  global _debugging
  
  _debugging = True
  
  debug.dprint("Enabled debugging")
  
  return
예제 #7
0
def DisableDebugging():
  global _debugging
  
  _debugging = False
  
  debug.dprint("Disabled debugging")
  
  return
예제 #8
0
def DisableDebugging():
    global _debugging

    _debugging = False

    debug.dprint("Disabled debugging")

    return
예제 #9
0
def EnableDebugging():
    global _debugging

    _debugging = True

    debug.dprint("Enabled debugging")

    return
예제 #10
0
def ReadMsh(filename):
    """
  Read a Gmsh msh file
  """

    fileHandle = open(filename, "rb")

    basename = filename.split(".")[0]
    hasHalo = filehandling.FileExists(basename + ".halo")

    # Read the MeshFormat section

    line = ReadNonCommentLine(fileHandle)
    assert (line == "$MeshFormat")

    line = ReadNonCommentLine(fileHandle)
    lineSplit = line.split()
    assert (len(lineSplit) == 3)
    version = lineSplit[0]
    fileType = int(lineSplit[1])
    dataSize = int(lineSplit[2])

    if version[0] == "4" and version < "4.1":
        raise Exception("gmshtools doesn't handle msh4 with minor version 0")

    if fileType == 1:
        # Binary format
        if version[0] == "4":
            mesh = ReadBinaryMshV4(fileHandle, dataSize)
        elif version[0] == "2":
            mesh = ReadBinaryMshV2(fileHandle, dataSize)
        else:
            raise Exception("Unknown gmsh major version")
    elif fileType == 0:
        # ASCII format
        if version[0] == "4":
            mesh = ReadAsciiMshV4(fileHandle)
        elif version[0] == "2":
            mesh = ReadAsciiMshV2(fileHandle)
        else:
            raise Exception("Unknown gmsh major version")
    else:
        raise Exception("File type " + str(fileType) + " not recognised")

    fileHandle.close()

    if hasHalo:
        # Read the .halo file
        debug.dprint("Reading .halo file")

        if mesh_halos.HaloIOSupport():
            halos = mesh_halos.ReadHalos(basename + ".halo")
            mesh.SetHalos(halos)
        else:
            debug.deprint("Warning: No .halo I/O support")

    return mesh
예제 #11
0
def Help():
  debug.dprint("Usage: gen_square_meshes [OPTIONS] ... NODES MESHES\n" + \
               "\n" + \
               "Options:\n" + \
               "\n" + \
               "-h  Display this help\n" + \
               "-v  Verbose mode", 0)
  
  return
예제 #12
0
def Help():
  debug.dprint("Usage: gen_square_meshes [OPTIONS] ... NODES MESHES\n" + \
               "\n" + \
               "Options:\n" + \
               "\n" + \
               "-h  Display this help\n" + \
               "-v  Verbose mode", 0)
  
  return
예제 #13
0
def Help():
  debug.dprint("Usage: statplot [OPTIONS] FILENAME [FILENAME ...]\n" + \
               "\n" + \
               "Options:\n" + \
               "\n" + \
               "-h  Display this help\n" + \
               "-v  Verbose mode",  0)

  return
예제 #14
0
파일: statplot.py 프로젝트: CoastED/coasted
def Help():
    debug.dprint("Usage: statplot [OPTIONS] FILENAME [FILENAME ...]\n" + \
                 "\n" + \
                 "Options:\n" + \
                 "\n" + \
                 "-h  Display this help\n" + \
                 "-v  Verbose mode",  0)

    return
예제 #15
0
def VtuStripFloatingNodes(vtu):
    """
  Strip floating (unconnected) nodes from the supplied vtu
  """

    nodeUsed = numpy.array(
        [False for i in range(vtu.ugrid.GetNumberOfPoints())])
    for i in range(vtu.ugrid.GetNumberOfCells()):
        cell = vtu.ugrid.GetCell(i)
        nodeIds = cell.GetPointIds()
        nodes = [nodeIds.GetId(i) for i in range(nodeIds.GetNumberOfIds())]
        nodeUsed[nodes] = True

    nodeMap = [None for i in range(vtu.ugrid.GetNumberOfPoints())]
    nnodes = 0
    for node, used in enumerate(nodeUsed):
        if used:
            nodeMap[node] = nnodes
            nnodes += 1
    nFloatingNodes = vtu.ugrid.GetNumberOfPoints() - nnodes
    debug.dprint("Floating nodes: " + str(nFloatingNodes))
    if nFloatingNodes == 0:
        return

    coords = vtu.GetLocations()
    points = vtk.vtkPoints()
    points.SetDataTypeToDouble()
    for node, coord in enumerate(coords):
        if nodeUsed[node]:
            points.InsertNextPoint(coord[0], coord[1], coord[2])
    vtu.ugrid.SetPoints(points)

    cells = vtk.vtkCellArray()
    for i in range(vtu.ugrid.GetNumberOfCells()):
        cell = vtu.ugrid.GetCell(i)
        nodeIds = cell.GetPointIds()
        nodes = [nodeIds.GetId(i) for i in range(nodeIds.GetNumberOfIds())]
        for i, node in enumerate(nodes):
            assert (not nodeMap[node] is None)
            nodeIds.SetId(i, nodeMap[node])
        cells.InsertNextCell(cell)
    vtu.ugrid.SetCells(vtu.ugrid.GetCellTypesArray(),
                       vtu.ugrid.GetCellLocationsArray(), cells)

    for fieldName in vtu.GetFieldNames():
        field = vtu.GetField(fieldName)
        shape = list(field.shape)
        shape[0] = nnodes
        nField = numpy.empty(shape)
        for node, nNode in enumerate(nodeMap):
            if not nNode is None:
                nField[nNode] = field[node]
        vtu.AddField(fieldName, nField)

    return
예제 #16
0
def SliceCoordsLinear(minVal,
                      maxVal,
                      minL,
                      divisions,
                      tolerance=calc.Epsilon()):
    """
  Generate one dimension of annulus slice coordinates based upon the supplied
  geometry information, with linearly stretched node spacing
  """

    assert (minL > 0.0)
    assert (divisions >= 4)
    assert (calc.IsEven(divisions))

    d = (maxVal - minVal) / 2.0
    n = divisions / 2

    # Perform a binary search for r - using a numerical solve via
    # scipy.optimize.fsolve seems to introduce too large an error
    minR = 1.0
    maxR = d / minL
    r = 0.0
    while True:
        # Calculate a new guess for r
        oldR = r
        r = (maxR + minR) / 2.0
        if calc.AlmostEquals(r, oldR, tolerance=tolerance):
            break

        # Calculate what value of d this implies
        dGuess = 0.0
        for i in range(n):
            dGuess += minL * (r**i)

        # Based upon the implied d, choose new bounds for r
        if calc.AlmostEquals(d, dGuess, tolerance=tolerance):
            break
        elif dGuess > d:
            maxR = r
        else:
            minR = r
    if calc.AlmostEquals(r, 1.0, tolerance=tolerance):
        raise Exception("No solution for r > 1.0 found")

    debug.dprint("r = " + str(r), 2)

    coords = [minVal]
    for i in range(divisions / 2 - 1):
        coords.insert(i + 1, coords[i] + (minL * (r**i)))
    coords.append((maxVal + minVal) / 2.0)
    coords.append(maxVal)
    for i in range(divisions / 2 - 1):
        coords.insert(len(coords) - i - 1, coords[-i - 1] - (minL * (r**i)))

    return coords
예제 #17
0
def VtuStripFloatingNodes(vtu):
  """
  Strip floating (unconnected) nodes from the supplied vtu
  """
  
  nodeUsed = numpy.array([False for i in range(vtu.ugrid.GetNumberOfPoints())])
  for i in range(vtu.ugrid.GetNumberOfCells()):
    cell = vtu.ugrid.GetCell(i)
    nodeIds = cell.GetPointIds()
    nodes = [nodeIds.GetId(i) for i in range(nodeIds.GetNumberOfIds())]
    nodeUsed[nodes] = True
  
  nodeMap = [None for i in range(vtu.ugrid.GetNumberOfPoints())]
  nnodes = 0
  for node, used in enumerate(nodeUsed):
    if used:
      nodeMap[node] = nnodes
      nnodes += 1
  nFloatingNodes = vtu.ugrid.GetNumberOfPoints() - nnodes
  debug.dprint("Floating nodes: " + str(nFloatingNodes))
  if nFloatingNodes == 0:
    return
  
  coords = vtu.GetLocations()
  points = vtk.vtkPoints()
  points.SetDataTypeToDouble()
  for node, coord in enumerate(coords):
    if nodeUsed[node]:
      points.InsertNextPoint(coord[0], coord[1], coord[2])
  vtu.ugrid.SetPoints(points)
  
  cells = vtk.vtkCellArray()
  for i in range(vtu.ugrid.GetNumberOfCells()):
    cell = vtu.ugrid.GetCell(i)
    nodeIds = cell.GetPointIds()
    nodes = [nodeIds.GetId(i) for i in range(nodeIds.GetNumberOfIds())]
    for i, node in enumerate(nodes):
      assert(not nodeMap[node] is None)
      nodeIds.SetId(i, nodeMap[node])      
    cells.InsertNextCell(cell)
  vtu.ugrid.SetCells(vtu.ugrid.GetCellTypesArray(), vtu.ugrid.GetCellLocationsArray(), cells)
  
  for fieldName in vtu.GetFieldNames():
    field = vtu.GetField(fieldName)
    shape = list(field.shape)
    shape[0] = nnodes
    nField = numpy.empty(shape)
    for node, nNode in enumerate(nodeMap):
      if not nNode is None:
        nField[nNode] = field[node]
    vtu.AddField(fieldName, nField)
  
  return
예제 #18
0
  def __init__(self, filename, latitudeName = "latitude", longitudeName = "longitude", timeName = "time"):
    self._file = netcdf.netcdf_file(filename, "r")
    self._latitudes = self.Values(latitudeName)
    self._longitudes = self.Values(longitudeName)
    self._times = self.Values(timeName)

    # Longitude wrap-around
    self._longitudes.append(self._longitudes[0] + 360.0)

    debug.dprint(self)

    return
예제 #19
0
def SliceCoordsLinear(minVal, maxVal, minL, divisions, tolerance = calc.Epsilon()):
  """
  Generate one dimension of annulus slice coordinates based upon the supplied
  geometry information, with linearly stretched node spacing
  """

  assert(minL > 0.0)
  assert(divisions >= 4)
  assert(calc.IsEven(divisions))
  
  d = (maxVal - minVal) / 2.0
  n = divisions / 2
  
  # Perform a binary search for r - using a numerical solve via
  # scipy.optimize.fsolve seems to introduce too large an error
  minR = 1.0
  maxR = d / minL
  r = 0.0
  while True:
    # Calculate a new guess for r
    oldR = r
    r = (maxR + minR) / 2.0
    if calc.AlmostEquals(r, oldR, tolerance = tolerance):
      break
      
    # Calculate what value of d this implies
    dGuess = 0.0
    for i in range(n):
      dGuess += minL * (r ** i)
      
    # Based upon the implied d, choose new bounds for r
    if calc.AlmostEquals(d, dGuess, tolerance = tolerance):
      break
    elif dGuess > d:
      maxR = r
    else:
      minR = r
  if calc.AlmostEquals(r, 1.0, tolerance = tolerance):
    raise Exception("No solution for r > 1.0 found")
      
  debug.dprint("r = " + str(r), 2)
  
  coords = [minVal]
  for i in range(divisions / 2 - 1):
    coords.insert(i + 1, coords[i] + (minL * (r ** i)))
  coords.append((maxVal + minVal) / 2.0)
  coords.append(maxVal)
  for i in range(divisions / 2 - 1):
    coords.insert(len(coords) - i - 1, coords[-i - 1] - (minL * (r ** i)))
    
  return coords
예제 #20
0
    def _initialise_parameters(self):
        """
    Initialise the parameters used in evaluating the Lomb-Scargle periodogram
    """

        self._mean = MeanVal(self._x)

        self._variance = 0.0
        for x in self._x:
            self._variance += (x - self._mean)**2
        self._variance /= float(self.DataPointsCount() - 1)

        debug.dprint("Mean = " + str(self._mean), 3)
        debug.dprint("Variance = " + str(self._variance), 3)

        return
예제 #21
0
    def __init__(self,
                 filename,
                 latitudeName="latitude",
                 longitudeName="longitude",
                 timeName="time"):
        self._file = netcdf.NetCDFFile(filename, "r")
        self._latitudes = self.Values(latitudeName)
        self._longitudes = self.Values(longitudeName)
        self._times = self.Values(timeName)

        # Longitude wrap-around
        self._longitudes.append(self._longitudes[0] + 360.0)

        debug.dprint(self)

        return
예제 #22
0
 def _initialise_parameters(self):
   """
   Initialise the parameters used in evaluating the Lomb-Scargle periodogram
   """
   
   self._mean = MeanVal(self._x)
   
   self._variance = 0.0
   for x in self._x:
     self._variance += (x - self._mean) ** 2
   self._variance /= float(self.DataPointsCount() - 1)
   
   debug.dprint("Mean = " + str(self._mean), 3)
   debug.dprint("Variance = " + str(self._variance), 3)
 
   return
예제 #23
0
def InterpolatedSSA(v, t, N_T, n, J=1, t0=None, t1=None):
    """
  Perform a singular systems analysis of the supplied non-uniform data using
  linear interpolation
  """

    if t0 is None:
        t0 = t[0]
    if t1 is None:
        t1 = t[-1]

    dt = (t1 - t0) / float(N_T)
    debug.dprint("Interpolation dt: " + str(dt))

    lt = [t0 + i * dt for i in range(N_T)]
    lv = LinearlyInterpolateField(v, t, lt)
    print(lv, lt)

    return SSA(lv, n, J=J)
예제 #24
0
def InterpolatedSSA(v, t, N_T, n, J = 1, t0 = None, t1 = None):
  """
  Perform a singular systems analysis of the supplied non-uniform data using
  linear interpolation
  """
  
  if t0 is None:
    t0 = t[0]
  if t1 is None:
    t1 = t[-1]
  
  dt = (t1 - t0) / float(N_T)
  debug.dprint("Interpolation dt: " + str(dt))
  
  lt = [t0 + i * dt for i in range(N_T)]
  lv = LinearlyInterpolateField(v, t, lt)
  print(lv, lt)
    
  return SSA(lv, n, J = J)
예제 #25
0
def FluidityBinary(binaries = ["dfluidity-debug", "dfluidity", "fluidity-debug", "fluidity"]):
  """
  Return the command used to call Fluidity
  """

  binary = None
  
  for possibleBinary in binaries:
    process = subprocess.Popen(["which", possibleBinary], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
    process.wait()
    if process.returncode == 0:
      binary = possibleBinary
      debug.dprint("Fluidity binary: " + str(process.stdout.readlines()[0]), newline = False)
      break
  
  if binary is None:
    raise Exception("Failed to find Fluidity binary")
  
  return binary
예제 #26
0
def SSA(v, n, J=1):
    """
  Perform a singular systems analysis of the supplied array of data. See:
    Inertia-Gravity Wave Generation by Baroclinic Instability, Tom Jacoby,
    First year report, AOPP, September 2007
  """

    N_T = len(v)
    N = N_T - (n - 1) * J

    shape = (n, N)
    debug.dprint("Assembling matrix for SSA, shape = " + str(shape))
    X = numpy.empty(shape)
    for i in range(N):
        for j in range(n):
            X[j, i] = v[i + j * J]
    theta = numpy.dot(X, X.transpose()) / float(N)
    del (X)

    debug.dprint("Performing eigendecomposition")
    return Eigendecomposition(theta, returnEigenvectors=True)
예제 #27
0
def SSA(v, n, J = 1):
  """
  Perform a singular systems analysis of the supplied array of data. See:
    Inertia-Gravity Wave Generation by Baroclinic Instability, Tom Jacoby,
    First year report, AOPP, September 2007
  """
  
  N_T = len(v)
  N = N_T - (n - 1) * J

  shape = (n, N)
  debug.dprint("Assembling matrix for SSA, shape = " + str(shape))
  X = numpy.empty(shape)
  for i in range(N):
    for j in range(n):
      X[j, i] = v[i + j * J]
  theta = numpy.dot(X, X.transpose()) / float(N)
  del(X)
  
  debug.dprint("Performing eigendecomposition")
  return Eigendecomposition(theta, returnEigenvectors = True)
예제 #28
0
if len(args) < 2:
    debug.FatalError("GMSH base name and vtu name required")
elif len(args) > 2:
    debug.FatalError("Unrecognised trailing argument")
meshBasename = args[0]
vtuFilename = args[1]

possibleMeshBasenames = glob.glob(meshBasename + "_?*.msh")
meshBasenames = []
meshIds = []
for possibleMeshBasename in possibleMeshBasenames:
    id = possibleMeshBasename[len(meshBasename) + 1:-4]
    try:
        id = int(id)
    except ValueError:
        continue

    meshBasenames.append(possibleMeshBasename[:-4])
    meshIds.append(id)

vtuBasename = os.path.basename(vtuFilename[:-len(vtuFilename.split(".")[-1]) -
                                           1])
vtuExt = vtuFilename[-len(vtuFilename.split(".")[-1]):]

vtu = vtktools.vtu(vtuFilename)
for i, meshBasename in enumerate(meshBasenames):
    debug.dprint("Processing mesh partition " + meshBasename)
    meshVtu = gmshtools.ReadMsh(meshBasename).ToVtu(includeSurface=False)
    partition = vtktools.RemappedVtu(vtu, meshVtu)
    partition.Write(vtuBasename + "_" + str(meshIds[i]) + "." + vtuExt)
예제 #29
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
예제 #30
0
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
예제 #31
0
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
예제 #32
0
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
예제 #33
0
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
예제 #34
0
def PvtuToVtu(pvtu, model = None, oldNodeIdToNew = [], oldCellIdToNew = [],
                    fieldlist = []):
  """
  Convert a parallel vtu to a serial vtu. Does nothing (except generate a copy)
  if the supplied vtu is already a serial vtu.
  """
  
  # Steps 1-5 are now handled by ModelPvtuToVtu (or aren't necessary if
  # additional information is passed to PvtuToVtu)
  if((model == None) or (len(oldNodeIdToNew) != pvtu.ugrid.GetNumberOfPoints()) 
                     or (len(oldCellIdToNew) != pvtu.ugrid.GetNumberOfCells())):
    result, oldNodeIdToNew, oldCellIdToNew = ModelPvtuToVtu(pvtu)
  else:
    result = model

  # Step 6: Generate the new point data
  for i in range(pvtu.ugrid.GetPointData().GetNumberOfArrays()):
    oldData = pvtu.ugrid.GetPointData().GetArray(i)
    name = pvtu.ugrid.GetPointData().GetArrayName(i)
    if len(fieldlist) > 0 and name not in fieldlist:
      continue
    debug.dprint("Processing point data " + name)
    components = oldData.GetNumberOfComponents()
    tuples = oldData.GetNumberOfTuples()
   
    newData = vtk.vtkDoubleArray()
    newData.SetName(name)
    newData.SetNumberOfComponents(components)
    newData.SetNumberOfValues(result.ugrid.GetNumberOfPoints()*components)
    for nodeId in range(tuples):
      newNodeId = oldNodeIdToNew[nodeId]
      if not newNodeId is None:
        for i in range(components):
          newData.SetValue(newNodeId * components + i, oldData.GetValue(nodeId * components + i))
    result.ugrid.GetPointData().AddArray(newData)
  
  # Step 7: Generate the new cell data
  for i in range(pvtu.ugrid.GetCellData().GetNumberOfArrays()):
    oldData = pvtu.ugrid.GetCellData().GetArray(i)
    name = pvtu.ugrid.GetCellData().GetArrayName(i)
    if len(fieldlist) > 0 and name not in fieldlist:
      continue
    debug.dprint("Processing cell data " + name)
    if name == "vtkGhostLevels":
      debug.dprint("Skipping ghost level data")
      continue
    components = oldData.GetNumberOfComponents()
    tuples = oldData.GetNumberOfTuples()
   
    newData = vtk.vtkDoubleArray()
    newData.SetName(name)
    newData.SetNumberOfComponents(components)
    newData.SetNumberOfValues(result.ugrid.GetNumberOfCells()*components)
    for cellId in range(tuples):
      newCellId = oldCellIdToNew[cellId]
      if not newCellId is None:
        for i in range(components):
          newData.SetValue(newCellId * components + i, oldData.GetValue(cellId * components + i))
    result.ugrid.GetCellData().AddArray(newData)
    
  return result
예제 #35
0
def PvtuToVtuRemoveDuplicateNodes(pvtu,  keepNode):
  # Detect duplicate nodes and remove them
    
  # Jumping through Python 2.3 hoops for cx1 - in >= 2.4, can just pass a cmp
  # argument to list.sort
  class LocationSorter(utils.Sorter):
    def __init__(self, x, y, order = [0, 1, 2]):
      utils.Sorter.__init__(self, x, y)
      self._order = order
    
      return
  
    def __cmp__(self, val):
      def cmp(x, y, order):
        for comp in order:        
          if x[comp] > y[comp]:
            return 1
          elif x[comp] < y[comp]:
            return -1
        
        return 0
        
      return cmp(self._key, val.GetKey(), self._order)
  
  def Dup(x, y, tol):
    for i, xVal in enumerate(x):
      if abs(xVal - y[i]) > tol:
        return False
        
    return True
      
  nodeIds = []
  oldNodeIdToNew = [None] * pvtu.ugrid.GetNumberOfPoints()

  locations = pvtu.GetLocations()
  lbound, ubound = VtuBoundingBox(pvtu).GetBounds()
  tol = calc.L2Norm([ubound[i] - lbound[i] for i in range(len(lbound))]) / 1.0e12
  debug.dprint("Duplicate node tolerance: " + str(tol))
  
  duplicateNodeMap = [None for i in range(pvtu.ugrid.GetNumberOfPoints())]
  duplicateNodeMapInverse = [[] for i in range(len(duplicateNodeMap))]
  # We need to sort the locations using all possible combinations of component
  # order, to take account of all possible floating point errors.
  orders = [[0], [[0, 1], [1, 0]], [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]][VtuDim(pvtu) - 1]
  for order in orders:  
    debug.dprint("Processing component order: " + str(order))
    
    # Generate a sorted list of locations, with their node IDs
    sortPack = [LocationSorter(location.tolist(), i, order) for i, location in enumerate(locations)]
    sortPack.sort()
    permutedLocations = [pack.GetKey() for pack in sortPack]
    permutedNodeIds = [pack.GetValue() for pack in sortPack]
    
    # This rather horrible construction maps all except the first node in each set
    # of duplicate nodes to the first node in the set of duplicate nodes, for the
    # sorted current non-ghost locations
    i = 0
    while i < len(permutedLocations) - 1:
      j = i
      while j < len(permutedLocations) - 1:
        if Dup(permutedLocations[i], permutedLocations[j + 1], tol):
          if keepNode[permutedNodeIds[j + 1]]:
            oldNodeId = permutedNodeIds[j + 1]
            newNodeId = permutedNodeIds[i]
            while not duplicateNodeMap[newNodeId] is None:
              newNodeId = duplicateNodeMap[newNodeId]
              if newNodeId == oldNodeId:
                # This is already mapped the other way
                break
            if newNodeId == oldNodeId:
              # Can only occur from early exit of the above loop
              j += 1
              continue
            
            def MapInverses(oldNodeId, newNodeId):
              for nodeId in duplicateNodeMapInverse[oldNodeId]:
                 assert(not nodeId == newNodeId)
                 assert(keepNode[newNodeId])
                 keepNode[nodeId] = False
                 duplicateNodeMap[nodeId] = newNodeId
                 duplicateNodeMapInverse[newNodeId].append(nodeId)
                 MapInverses(nodeId, newNodeId)
              duplicateNodeMapInverse[oldNodeId] = []
               
              return
              
            keepNode[newNodeId] = True
            keepNode[oldNodeId] = False 
            # Map everything mapped to the old node ID to the new node ID
            MapInverses(oldNodeId, newNodeId)
            duplicateNodeMap[oldNodeId] = newNodeId
            duplicateNodeMapInverse[newNodeId].append(oldNodeId)
          j += 1
        else:
          break
      i = j
      i += 1
    
    debug.dprint("Non-ghost nodes: " + str(keepNode.count(True)))
      
  # Collect the final non-ghost node IDs and generate the node renumbering map
  nodeIds = []
  index = 0
  for i, keep in enumerate(keepNode):
    if keep:
      nodeIds.append(i)
      oldNodeIdToNew[i] = index
      index += 1
  for i, nodeId in enumerate(duplicateNodeMap):
    if not nodeId is None: 
      assert(oldNodeIdToNew[i] is None)
      assert(not oldNodeIdToNew[nodeId] is None)
      oldNodeIdToNew[i] = oldNodeIdToNew[nodeId]
  
  debug.dprint("Non-ghost nodes (pass 2): " + str(len(nodeIds)))

  return oldNodeIdToNew, nodeIds
예제 #36
0
def ModelPvtuToVtu(pvtu):
  """
  Convert a parallel vtu to a serial vtu but without any fields. Does nothing
  (except generate a copy) if the supplied vtu is already a serial vtu.
  """
  
  # Step 1: Extract the ghost levels, and check that we have a parallel vtu
  
  result = vtu()
  ghostLevel = pvtu.ugrid.GetCellData().GetArray("vtkGhostLevels")
  if ghostLevel is None:
    # We have a serial vtu
    debug.deprint("Warning: input file contains no vtkGhostLevels")
    ghostLevel = [0 for i in range(pvtu.ugrid.GetNumberOfCells())]
  else:
    # We have a parallel vtu
    ghostLevel = [ghostLevel.GetValue(i) for i in range(ghostLevel.GetNumberOfComponents() * ghostLevel.GetNumberOfTuples())]
  
  # Step 2: Collect the non-ghost cell IDs
  
  debug.dprint("Input cells: " + str(pvtu.ugrid.GetNumberOfCells()))
  
  cellIds = []
  keepCell = [False for i in range(pvtu.ugrid.GetNumberOfCells())]
  oldCellIdToNew = [None for i in range(pvtu.ugrid.GetNumberOfCells())]
  
  # Collect the new non-ghost cell IDs and generate the cell renumbering map
  index = 0
  for i, level in enumerate(ghostLevel):
    if calc.AlmostEquals(level, 0.0):
      cellIds.append(i)
      keepCell[i] = True
      oldCellIdToNew[i] = index
      index += 1
      
  debug.dprint("Non-ghost cells: " + str(len(cellIds)))
  
  # Step 3: Collect the non-ghost node IDs
  
  debug.dprint("Input points: " + str(pvtu.ugrid.GetNumberOfPoints()))
 
  keepNode = [False for i in range(pvtu.ugrid.GetNumberOfPoints())]
  
  # Find a list of candidate non-ghost node IDs, based on nodes attached to
  # non-ghost cells
  keepNodeCount = 0
  for cellId in cellIds:
    cellNodeIds = pvtu.ugrid.GetCell(cellId).GetPointIds()
    cellNodeIds = [cellNodeIds.GetId(i) for i in range(cellNodeIds.GetNumberOfIds())]
    keepNodeCount += len(cellNodeIds)
    for nodeId in cellNodeIds:
      keepNode[nodeId] = True
      
  uniqueKeepNodeCount = keepNode.count(True)
  debug.dprint("Non-ghost nodes (pass 1): " + str(uniqueKeepNodeCount))
  if uniqueKeepNodeCount==keepNodeCount:
    debug.dprint("Assuming pvtu is discontinuous")
    # we're keeping all non-ghost nodes:
    nodeIds = [i for i in range(pvtu.ugrid.GetNumberOfPoints()) if keepNode[i]]
    oldNodeIdToNew = numpy.array([None]*pvtu.ugrid.GetNumberOfPoints())
    oldNodeIdToNew[nodeIds] = range(keepNodeCount)
  else:
    # for the CG case we still have duplicate nodes that need to be removed
    oldNodeIdToNew, nodeIds = PvtuToVtuRemoveDuplicateNodes(pvtu, keepNode)

  # Step 4: Generate the new locations
  locations = pvtu.GetLocations()
  locations = numpy.array([locations[i] for i in nodeIds])
  points = vtk.vtkPoints()
  points.SetDataTypeToDouble()
  for location in locations:
    points.InsertNextPoint(location)
  result.ugrid.SetPoints(points)

  # Step 5: Generate the new cells
  for cellId in cellIds:
    cell = pvtu.ugrid.GetCell(cellId)
    cellNodeIds = cell.GetPointIds()
    cellNodeIds = [cellNodeIds.GetId(i) for i in range(cellNodeIds.GetNumberOfIds())]
    idList = vtk.vtkIdList()
    for nodeId in cellNodeIds:
      oldNodeId = nodeId
      nodeId = oldNodeIdToNew[nodeId]
      assert(not nodeId is None)
      assert(nodeId >= 0)
      assert(nodeId <= len(nodeIds))
      idList.InsertNextId(nodeId)
    result.ugrid.InsertNextCell(cell.GetCellType(), idList)

  return result, oldNodeIdToNew, oldCellIdToNew
예제 #37
0
def ModelPvtuToVtu(pvtu):
    """
  Convert a parallel vtu to a serial vtu but without any fields. Does nothing
  (except generate a copy) if the supplied vtu is already a serial vtu.
  """

    # Step 1: Extract the ghost levels, and check that we have a parallel vtu

    result = vtu()
    ghostLevel = pvtu.ugrid.GetCellData().GetArray("vtkGhostLevels")
    if ghostLevel is None:
        # We have a serial vtu
        debug.deprint("Warning: VtuFromPvtu passed a serial vtu")
        ghostLevel = [0 for i in range(vtu.ugrid.GetNumberOfCells())]
    else:
        # We have a parallel vtu
        ghostLevel = [
            ghostLevel.GetValue(i)
            for i in range(ghostLevel.GetNumberOfComponents() *
                           ghostLevel.GetNumberOfTuples())
        ]

    # Step 2: Collect the non-ghost cell IDs

    debug.dprint("Input cells: " + str(pvtu.ugrid.GetNumberOfCells()))

    cellIds = []
    keepCell = [False for i in range(pvtu.ugrid.GetNumberOfCells())]
    oldCellIdToNew = [None for i in range(pvtu.ugrid.GetNumberOfCells())]

    # Collect the new non-ghost cell IDs and generate the cell renumbering map
    index = 0
    for i, level in enumerate(ghostLevel):
        if calc.AlmostEquals(level, 0.0):
            cellIds.append(i)
            keepCell[i] = True
            oldCellIdToNew[i] = index
            index += 1

    debug.dprint("Non-ghost cells: " + str(len(cellIds)))

    # Step 3: Collect the non-ghost node IDs

    debug.dprint("Input points: " + str(pvtu.ugrid.GetNumberOfPoints()))

    nodeIds = []
    keepNode = [False for i in range(pvtu.ugrid.GetNumberOfPoints())]
    oldNodeIdToNew = [None for i in range(pvtu.ugrid.GetNumberOfPoints())]

    # Find a list of candidate non-ghost node IDs, based on nodes attached to
    # non-ghost cells
    for cellId in cellIds:
        cellNodeIds = pvtu.ugrid.GetCell(cellId).GetPointIds()
        cellNodeIds = [
            cellNodeIds.GetId(i) for i in range(cellNodeIds.GetNumberOfIds())
        ]
        for nodeId in cellNodeIds:
            keepNode[nodeId] = True

    debug.dprint("Non-ghost nodes (pass 1): " + str(keepNode.count(True)))

    # Detect duplicate nodes

    # Jumping through Python 2.3 hoops for cx1 - in >= 2.4, can just pass a cmp
    # argument to list.sort
    class LocationSorter(utils.Sorter):
        def __init__(self, x, y, order=[0, 1, 2]):
            utils.Sorter.__init__(self, x, y)
            self._order = order

            return

        def __cmp__(self, val):
            def cmp(x, y, order):
                for comp in order:
                    if x[comp] > y[comp]:
                        return 1
                    elif x[comp] < y[comp]:
                        return -1

                return 0

            return cmp(self._key, val.GetKey(), self._order)

    def Dup(x, y, tol):
        for i, xVal in enumerate(x):
            if abs(xVal - y[i]) > tol:
                return False

        return True

    locations = pvtu.GetLocations()
    lbound, ubound = VtuBoundingBox(pvtu).GetBounds()
    tol = calc.L2Norm([ubound[i] - lbound[i]
                       for i in range(len(lbound))]) / 1.0e12
    debug.dprint("Duplicate node tolerance: " + str(tol))

    duplicateNodeMap = [None for i in range(pvtu.ugrid.GetNumberOfPoints())]
    duplicateNodeMapInverse = [[] for i in range(len(duplicateNodeMap))]
    # We need to sort the locations using all possible combinations of component
    # order, to take account of all possible floating point errors.
    orders = [[0], [[0, 1], [1, 0]],
              [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1],
               [2, 1, 0]]][VtuDim(pvtu) - 1]
    for order in orders:
        debug.dprint("Processing component order: " + str(order))

        # Generate a sorted list of locations, with their node IDs
        sortPack = [
            LocationSorter(location.tolist(), i, order)
            for i, location in enumerate(locations)
        ]
        sortPack.sort()
        permutedLocations = [pack.GetKey() for pack in sortPack]
        permutedNodeIds = [pack.GetValue() for pack in sortPack]

        # This rather horrible construction maps all except the first node in each set
        # of duplicate nodes to the first node in the set of duplicate nodes, for the
        # sorted current non-ghost locations
        i = 0
        while i < len(permutedLocations) - 1:
            j = i
            while j < len(permutedLocations) - 1:
                if Dup(permutedLocations[i], permutedLocations[j + 1], tol):
                    if keepNode[permutedNodeIds[j + 1]]:
                        oldNodeId = permutedNodeIds[j + 1]
                        newNodeId = permutedNodeIds[i]
                        while not duplicateNodeMap[newNodeId] is None:
                            newNodeId = duplicateNodeMap[newNodeId]
                            if newNodeId == oldNodeId:
                                # This is already mapped the other way
                                break
                        if newNodeId == oldNodeId:
                            # Can only occur from early exit of the above loop
                            j += 1
                            continue

                        def MapInverses(oldNodeId, newNodeId):
                            for nodeId in duplicateNodeMapInverse[oldNodeId]:
                                assert (not nodeId == newNodeId)
                                assert (keepNode[newNodeId])
                                keepNode[nodeId] = False
                                duplicateNodeMap[nodeId] = newNodeId
                                duplicateNodeMapInverse[newNodeId].append(
                                    nodeId)
                                MapInverses(nodeId, newNodeId)
                            duplicateNodeMapInverse[oldNodeId] = []

                            return

                        keepNode[newNodeId] = True
                        keepNode[oldNodeId] = False
                        # Map everything mapped to the old node ID to the new node ID
                        MapInverses(oldNodeId, newNodeId)
                        duplicateNodeMap[oldNodeId] = newNodeId
                        duplicateNodeMapInverse[newNodeId].append(oldNodeId)
                    j += 1
                else:
                    break
            i = j
            i += 1

        debug.dprint("Non-ghost nodes: " + str(keepNode.count(True)))

    # Collect the final non-ghost node IDs and generate the node renumbering map
    nodeIds = []
    index = 0
    for i, keep in enumerate(keepNode):
        if keep:
            nodeIds.append(i)
            oldNodeIdToNew[i] = index
            index += 1
    for i, nodeId in enumerate(duplicateNodeMap):
        if not nodeId is None:
            assert (oldNodeIdToNew[i] is None)
            assert (not oldNodeIdToNew[nodeId] is None)
            oldNodeIdToNew[i] = oldNodeIdToNew[nodeId]

    debug.dprint("Non-ghost nodes (pass 2): " + str(len(nodeIds)))

    # Step 4: Generate the new locations
    locations = pvtu.GetLocations()
    locations = numpy.array([locations[i] for i in nodeIds])
    points = vtk.vtkPoints()
    points.SetDataTypeToDouble()
    for location in locations:
        points.InsertNextPoint(location)
    result.ugrid.SetPoints(points)

    # Step 5: Generate the new cells
    for cellId in cellIds:
        cell = pvtu.ugrid.GetCell(cellId)
        cellNodeIds = cell.GetPointIds()
        cellNodeIds = [
            cellNodeIds.GetId(i) for i in range(cellNodeIds.GetNumberOfIds())
        ]
        idList = vtk.vtkIdList()
        for nodeId in cellNodeIds:
            oldNodeId = nodeId
            nodeId = oldNodeIdToNew[nodeId]
            assert (not nodeId is None)
            assert (nodeId >= 0)
            assert (nodeId <= len(nodeIds))
            idList.InsertNextId(nodeId)
        result.ugrid.InsertNextCell(cell.GetCellType(), idList)

    return result, oldNodeIdToNew, oldCellIdToNew
예제 #38
0
def PrintVtu(vtu, debugLevel = 0):
  """
  Print the supplied vtu
  """
  
  debug.dprint("Filename: " + str(vtu.filename), debugLevel)
  debug.dprint("Dimension: " + str(VtuDim(vtu)), debugLevel)
  debug.dprint("Bounding box: " + str(VtuBoundingBox(vtu)), debugLevel)
  debug.dprint("Nodes: " + str(vtu.ugrid.GetNumberOfPoints()), debugLevel)
  debug.dprint("Elements: " + str(vtu.ugrid.GetNumberOfCells()), debugLevel)
  debug.dprint("Fields: " + str(len(vtu.GetFieldNames())), debugLevel)
  for fieldName in vtu.GetFieldNames():
    string = fieldName + ", "
    rank = VtuFieldRank(vtu, fieldName)
    if rank == 0:
      string += "scalar"
    elif rank == 1:
      string += "vector"
    elif rank == 2:
      string += "tensor"
    else:
      string += "unknown"
    string += " field with shape " + str(VtuFieldShape(vtu, fieldName))
    debug.dprint(string, debugLevel)
  debug.dprint("Cell fields: " + str(len(VtuGetCellFieldNames(vtu))), debugLevel)
  for fieldName in VtuGetCellFieldNames(vtu):
    string = fieldName
    debug.dprint(string, debugLevel)
  
  return
예제 #39
0
def TimeAveragedVtu(filenames, timeFieldName = "Time", baseMesh = None, baseVtu = None):
  """
  Perform a time weighted average of vtus with the supplied filenames. The
  filenames must be in time order.
  """
  
  debug.dprint("Computing time averaged vtu")
  
  if not baseMesh is None:
    assert(baseVtu is None)
    result = baseMesh.ToVtu()
  elif not baseVtu is None:
    assert(baseMesh is None)
    result = CopyVtu(baseVtu)
  else:
    result = None
  
  if len(filenames) == 0:
    if result is None:
      return vtu()
    else:
      return result
  
  startTime = None
  finalTime = None
  lastDt = None
  nextInputVtu = None
  for i, filename in enumerate(filenames): 
    debug.dprint("Processing file " + filename)
   
    if nextInputVtu is None:  
      inputVtu = vtu(filename)
    else:
      inputVtu = nextInputVtu
    
    if result is None:
      result = vtu()
      # Add the points
      result.ugrid.SetPoints(inputVtu.ugrid.GetPoints())
      # Add the cells
      result.ugrid.SetCells(inputVtu.ugrid.GetCellTypesArray(), inputVtu.ugrid.GetCellLocationsArray(), inputVtu.ugrid.GetCells())
      
    if len(filenames) == 1:
      weight = 1.0
    else:
      # Trapezium rule weighting
      weight = 0.0
      if not lastDt is None:
        weight += lastDt
      
      timeField = inputVtu.GetScalarField(timeFieldName)
      assert(len(timeField) > 0)
      if startTime is None:
        startTime = timeField[0]
      
      if i < len(filenames) - 1:
        nextInputVtu = vtu(filenames[i + 1])
        nextTimeField = nextInputVtu.GetScalarField(timeFieldName)
        assert(len(nextTimeField) > 0)
        if finalTime is None:
          finalTime = nextTimeField[0]
          
        dt = nextTimeField[0] - timeField[0]
        lastDt = dt
        weight += dt
      
      weight /= 2.0
    debug.dprint("weight = " + str(weight))
    
    if i == 0:
      if not VtuMatchLocations(inputVtu, result):
        inputVtu = RemappedVtu(inputVtu, result)
      for fieldName in inputVtu.GetFieldNames():
        result.AddField(fieldName, inputVtu.GetField(fieldName) * weight)
    else:
      AddtoVtu(result, inputVtu, scale = weight)
  
  if len(filenames) > 1:
    debug.dprint("Start time = " + str(startTime))
    debug.dprint("Final time = " + str(finalTime))
    DivideVtu(result, finalTime - startTime)
  
  debug.dprint("Finished computing time averaged vtu")
  
  return result
예제 #40
0
def PvtuToVtu(pvtu,
              model=None,
              oldNodeIdToNew=[],
              oldCellIdToNew=[],
              fieldlist=[]):
    """
  Convert a parallel vtu to a serial vtu. Does nothing (except generate a copy)
  if the supplied vtu is already a serial vtu.
  """

    # Steps 1-5 are now handled by ModelPvtuToVtu (or aren't necessary if
    # additional information is passed to PvtuToVtu)
    if ((model == None)
            or (len(oldNodeIdToNew) != pvtu.ugrid.GetNumberOfPoints())
            or (len(oldCellIdToNew) != pvtu.ugrid.GetNumberOfCells())):
        result, oldNodeIdToNew, oldCellIdToNew = ModelPvtuToVtu(pvtu)
    else:
        result = model

    # Step 6: Generate the new point data
    for i in range(pvtu.ugrid.GetPointData().GetNumberOfArrays()):
        oldData = pvtu.ugrid.GetPointData().GetArray(i)
        name = pvtu.ugrid.GetPointData().GetArrayName(i)
        if len(fieldlist) > 0 and name not in fieldlist:
            continue
        debug.dprint("Processing point data " + name)
        components = oldData.GetNumberOfComponents()
        tuples = oldData.GetNumberOfTuples()

        newData = vtk.vtkDoubleArray()
        newData.SetName(name)
        newData.SetNumberOfComponents(components)
        newData.SetNumberOfValues(result.ugrid.GetNumberOfPoints() *
                                  components)
        for nodeId in range(tuples):
            newNodeId = oldNodeIdToNew[nodeId]
            if not newNodeId is None:
                for i in range(components):
                    newData.SetValue(newNodeId * components + i,
                                     oldData.GetValue(nodeId * components + i))
        result.ugrid.GetPointData().AddArray(newData)

    # Step 7: Generate the new cell data
    for i in range(pvtu.ugrid.GetCellData().GetNumberOfArrays()):
        oldData = pvtu.ugrid.GetCellData().GetArray(i)
        name = pvtu.ugrid.GetCellData().GetArrayName(i)
        if len(fieldlist) > 0 and name not in fieldlist:
            continue
        debug.dprint("Processing cell data " + name)
        if name == "vtkGhostLevels":
            debug.dprint("Skipping ghost level data")
            continue
        components = oldData.GetNumberOfComponents()
        tuples = oldData.GetNumberOfTuples()

        newData = vtk.vtkDoubleArray()
        newData.SetName(name)
        newData.SetNumberOfComponents(components)
        newData.SetNumberOfValues(result.ugrid.GetNumberOfCells() * components)
        for cellId in range(tuples):
            newCellId = oldCellIdToNew[cellId]
            if not newCellId is None:
                for i in range(components):
                    newData.SetValue(newCellId * components + i,
                                     oldData.GetValue(cellId * components + i))
        result.ugrid.GetCellData().AddArray(newData)

    return result
예제 #41
0
def ReadMsh(filename):
  """
  Read a Gmsh msh file
  """
      
  def ReadNonCommentLine(fileHandle):
    line = fileHandle.readline().decode("utf8")
    while len(line) > 0:
      line = line.strip()
      if len(line) > 0:
        return line
      line = fileHandle.readline().decode("utf8")
      
    return line
  
  fileHandle = open(filename, "rb")

  basename = filename.split(".")[0]
  hasHalo = filehandling.FileExists(basename + ".halo")
  
  # Read the MeshFormat section
  
  line = ReadNonCommentLine(fileHandle)
  assert(line == "$MeshFormat")
  
  line = ReadNonCommentLine(fileHandle)
  lineSplit = line.split()
  assert(len(lineSplit) == 3)
  version = 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
예제 #42
0
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
예제 #43
0
def LineVtuCut(inputVtu, origin = (0.0, 0.0, 0.0), direction = (1.0, 0.0, 0.0)):
  """
  Perform a plane-plane double cut to form a 1D line (in 3D space)
  """
  
  assert(len(origin) == 3)
  assert(len(direction) == 3)
   
  # Copy the input line direction
  x0 = direction[0]
  y0 = direction[1]
  z0 = direction[2]
  
  # To form the line from two planar cuts, we need two normal vectors at right
  # angles to the line direction.
  
  # Form the first normal vector by imposing x0 dot x1 = 0, with one component
  # of x1 equal to one and one equal to zero, where the component in x0
  # corresponding to the remaining third component is non-zero
  if calc.AlmostEquals(z0, 0.0):
    if calc.AlmostEquals(y0, 0.0):
      if calc.AlmostEquals(x0, 0.0):
        raise Exception("Direction has zero length")
      y1 = 1.0
      z1 = 0.0
      # x1 = -(y0 y1 + z0 z1) / x0
      x1 = -y0 / x0
    else:
      x1 = 1.0
      z1 = 0.0
      # y1 = -(x0 x1 + z0 z1) / y0
      y1 = - x0 / y0 
  else:
    x1 = 1.0
    y1 = 0.0
    # z1 = -(x0 x1 + y0 y1) / z0
    z1 = - x0 / z0
  # Normalise the first normal vector
  mag = calc.L2Norm([x1, y1, z1])
  x1 /= mag
  y1 /= mag
  z1 /= mag
  
  # Form the second normal vector via a cross product
  x2 = y0 * z1 - z0 * y1
  y2 = z0 * x1 - x0 * z1
  z2 = x0 * y1 - y0 * x1
  # Normalise the second normal vector
  mag = calc.L2Norm([x2, y2, z2])
  x2 /= mag
  y2 /= mag
  z2 /= mag
  
  normal1 = (x1, y1, z1)
  normal2 = (x2, y2, z2)
  debug.dprint("Normal 1 = " + str(normal1))
  debug.dprint("Normal 2 = " + str(normal2))
  
  # Perform the cuts
  cutVtu = PlanarVtuCut(inputVtu, origin, normal1)
  cutVtu = PlanarVtuCut(cutVtu, origin, normal2)
  
  return cutVtu
예제 #44
0
if len(args) < 2:
  debug.FatalError("GMSH base name and vtu name required")
elif len(args) > 2:
  debug.FatalError("Unrecognised trailing argument")
meshBasename = args[0]
vtuFilename = args[1]

possibleMeshBasenames = glob.glob(meshBasename + "_?*.msh")
meshBasenames = []
meshIds = []
for possibleMeshBasename in possibleMeshBasenames:
  id = possibleMeshBasename[len(meshBasename) + 1:-4]
  try:
    id = int(id)
  except ValueError:
    continue
    
  meshBasenames.append(possibleMeshBasename[:-4])
  meshIds.append(id)

vtuBasename = os.path.basename(vtuFilename[:-len(vtuFilename.split(".")[-1]) - 1])
vtuExt = vtuFilename[-len(vtuFilename.split(".")[-1]):]

vtu = vtktools.vtu(vtuFilename)
for i, meshBasename in enumerate(meshBasenames):
  debug.dprint("Processing mesh partition " + meshBasename)
  meshVtu = gmshtools.ReadMsh(meshBasename).ToVtu(includeSurface = False)
  partition = vtktools.RemappedVtu(vtu, meshVtu)
  partition.Write(vtuBasename + "_" + str(meshIds[i]) + "." + vtuExt)
예제 #45
0
if len(args) > 3:
  debug.FatalError("Unrecognised trailing argument")
inputProject = args[0]

if len(args) == 2:
  try:
    firstId = int(args[1])
    lastId = firstId
  except ValueError:
    debug.FatalError("Invalid first dump ID")

if len(args) == 3:
  try:
    firstId = int(args[1])
    lastId = int(args[2])
    assert(lastId >= firstId)
  except:
    debug.FatalError("Invalid last dump ID")
 
if len(args) == 1:
  filenames = [inputProject + ".pvtu"]
else:
  filenames = fluidity_tools.VtuFilenames(inputProject, firstId, lastId = lastId, extension = ".pvtu")

for filename in filenames:
  debug.dprint("Processing file: " + filename)

  vtu = vtktools.vtu(filename)
  vtu = vtktools.VtuFromPvtu(vtu)
  vtu.Write(filename[:-5] + ".vtu")
예제 #46
0
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
예제 #47
0
def PrintVtu(vtu, debugLevel=0):
    """
  Print the supplied vtu
  """

    debug.dprint("Filename: " + str(vtu.filename), debugLevel)
    debug.dprint("Dimension: " + str(VtuDim(vtu)), debugLevel)
    debug.dprint("Bounding box: " + str(VtuBoundingBox(vtu)), debugLevel)
    debug.dprint("Nodes: " + str(vtu.ugrid.GetNumberOfPoints()), debugLevel)
    debug.dprint("Elements: " + str(vtu.ugrid.GetNumberOfCells()), debugLevel)
    debug.dprint("Fields: " + str(len(vtu.GetFieldNames())), debugLevel)
    for fieldName in vtu.GetFieldNames():
        string = fieldName + ", "
        rank = VtuFieldRank(vtu, fieldName)
        if rank == 0:
            string += "scalar"
        elif rank == 1:
            string += "vector"
        elif rank == 2:
            string += "tensor"
        else:
            string += "unknown"
        string += " field with shape " + str(VtuFieldShape(vtu, fieldName))
        debug.dprint(string, debugLevel)
    debug.dprint("Cell fields: " + str(len(VtuGetCellFieldNames(vtu))),
                 debugLevel)
    for fieldName in VtuGetCellFieldNames(vtu):
        string = fieldName
        debug.dprint(string, debugLevel)

    return
예제 #48
0
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
예제 #49
0
파일: genpvtu.py 프로젝트: Torgier/fluidity
import os
import sys
import tempfile
import vtk

import fluidity.diagnostics.debug as debug
import fluidity.diagnostics.filehandling as filehandling
import fluidity.diagnostics.fluiditytools as fluiditytools
import fluidity.diagnostics.vtutools as vtktools

if not len(sys.argv) == 2:
  print "Usage: genpvtu basename"
  sys.exit(1)
basename = sys.argv[1]
debug.dprint("vtu basename: " + basename)
nPieces = fluiditytools.FindMaxVtuId(basename) + 1
debug.dprint("Number of pieces: " + str(nPieces))

# Write to a temporary directory so that the first piece isn't overwritten
tempDir = tempfile.mkdtemp()

# Create the parallel writer
writer = vtk.vtkXMLPUnstructuredGridWriter()
writer.SetNumberOfPieces(nPieces)
writer.WriteSummaryFileOn()
pvtuName = basename + ".pvtu"
writer.SetFileName(os.path.join(tempDir, pvtuName))

# Load in the first piece, so that the parallel writer has something to do (and
# knows which fields we have)
예제 #50
0
from __future__ import print_function
import os
import sys
import tempfile
import vtk

import fluidity.diagnostics.debug as debug
import fluidity.diagnostics.filehandling as filehandling
import fluidity.diagnostics.fluiditytools as fluiditytools
import fluidity.diagnostics.vtutools as vtktools

if not len(sys.argv) == 2:
    print("Usage: genpvtu basename")
    sys.exit(1)
basename = sys.argv[1]
debug.dprint("vtu basename: " + basename)
nPieces = fluiditytools.FindMaxVtuId(basename) + 1
debug.dprint("Number of pieces: " + str(nPieces))

# Write to a temporary directory so that the first piece isn't overwritten
tempDir = tempfile.mkdtemp()

# Create the parallel writer
writer = vtk.vtkXMLPUnstructuredGridWriter()
writer.SetNumberOfPieces(nPieces)
writer.WriteSummaryFileOn()
pvtuName = basename + ".pvtu"
writer.SetFileName(os.path.join(tempDir, pvtuName))

# Load in the first piece, so that the parallel writer has something to do (and
# knows which fields we have)
예제 #51
0
def TimeAveragedVtu(filenames,
                    timeFieldName="Time",
                    baseMesh=None,
                    baseVtu=None):
    """
  Perform a time weighted average of vtus with the supplied filenames. The
  filenames must be in time order.
  """

    debug.dprint("Computing time averaged vtu")

    if not baseMesh is None:
        assert (baseVtu is None)
        result = baseMesh.ToVtu()
    elif not baseVtu is None:
        assert (baseMesh is None)
        result = CopyVtu(baseVtu)
    else:
        result = None

    if len(filenames) == 0:
        if result is None:
            return vtu()
        else:
            return result

    startTime = None
    finalTime = None
    lastDt = None
    nextInputVtu = None
    for i, filename in enumerate(filenames):
        debug.dprint("Processing file " + filename)

        if nextInputVtu is None:
            inputVtu = vtu(filename)
        else:
            inputVtu = nextInputVtu

        if result is None:
            result = vtu()
            # Add the points
            result.ugrid.SetPoints(inputVtu.ugrid.GetPoints())
            # Add the cells
            result.ugrid.SetCells(inputVtu.ugrid.GetCellTypesArray(),
                                  inputVtu.ugrid.GetCellLocationsArray(),
                                  inputVtu.ugrid.GetCells())

        if len(filenames) == 1:
            weight = 1.0
        else:
            # Trapezium rule weighting
            weight = 0.0
            if not lastDt is None:
                weight += lastDt

            timeField = inputVtu.GetScalarField(timeFieldName)
            assert (len(timeField) > 0)
            if startTime is None:
                startTime = timeField[0]

            if i < len(filenames) - 1:
                nextInputVtu = vtu(filenames[i + 1])
                nextTimeField = nextInputVtu.GetScalarField(timeFieldName)
                assert (len(nextTimeField) > 0)
                if finalTime is None:
                    finalTime = nextTimeField[0]

                dt = nextTimeField[0] - timeField[0]
                lastDt = dt
                weight += dt

            weight /= 2.0
        debug.dprint("weight = " + str(weight))

        if i == 0:
            if not VtuMatchLocations(inputVtu, result):
                inputVtu = RemappedVtu(inputVtu, result)
            for fieldName in inputVtu.GetFieldNames():
                result.AddField(fieldName,
                                inputVtu.GetField(fieldName) * weight)
        else:
            AddtoVtu(result, inputVtu, scale=weight)

    if len(filenames) > 1:
        debug.dprint("Start time = " + str(startTime))
        debug.dprint("Final time = " + str(finalTime))
        DivideVtu(result, finalTime - startTime)

    debug.dprint("Finished computing time averaged vtu")

    return result
예제 #52
0
def EnablePsyco():
  if PsycoSupport():
    psyco.full()
    debug.dprint("Enabled psyco specialising compiler")
  
  return
예제 #53
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
예제 #54
0
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
예제 #55
0
def LineVtuCut(inputVtu, origin=(0.0, 0.0, 0.0), direction=(1.0, 0.0, 0.0)):
    """
  Perform a plane-plane double cut to form a 1D line (in 3D space)
  """

    assert (len(origin) == 3)
    assert (len(direction) == 3)

    # Copy the input line direction
    x0 = direction[0]
    y0 = direction[1]
    z0 = direction[2]

    # To form the line from two planar cuts, we need two normal vectors at right
    # angles to the line direction.

    # Form the first normal vector by imposing x0 dot x1 = 0, with one component
    # of x1 equal to one and one equal to zero, where the component in x0
    # corresponding to the remaining third component is non-zero
    if calc.AlmostEquals(z0, 0.0):
        if calc.AlmostEquals(y0, 0.0):
            if calc.AlmostEquals(x0, 0.0):
                raise Exception("Direction has zero length")
            y1 = 1.0
            z1 = 0.0
            # x1 = -(y0 y1 + z0 z1) / x0
            x1 = -y0 / x0
        else:
            x1 = 1.0
            z1 = 0.0
            # y1 = -(x0 x1 + z0 z1) / y0
            y1 = -x0 / y0
    else:
        x1 = 1.0
        y1 = 0.0
        # z1 = -(x0 x1 + y0 y1) / z0
        z1 = -x0 / z0
    # Normalise the first normal vector
    mag = calc.L2Norm([x1, y1, z1])
    x1 /= mag
    y1 /= mag
    z1 /= mag

    # Form the second normal vector via a cross product
    x2 = y0 * z1 - z0 * y1
    y2 = z0 * x1 - x0 * z1
    z2 = x0 * y1 - y0 * x1
    # Normalise the second normal vector
    mag = calc.L2Norm([x2, y2, z2])
    x2 /= mag
    y2 /= mag
    z2 /= mag

    normal1 = (x1, y1, z1)
    normal2 = (x2, y2, z2)
    debug.dprint("Normal 1 = " + str(normal1))
    debug.dprint("Normal 2 = " + str(normal2))

    # Perform the cuts
    cutVtu = PlanarVtuCut(inputVtu, origin, normal1)
    cutVtu = PlanarVtuCut(cutVtu, origin, normal2)

    return cutVtu