Ejemplo n.º 1
0
    def __init__(self, dx = 1., dy = 1., nx = 1, ny = 1,
                 _RepresentationClass=_Grid2DRepresentation, _TopologyClass=_Mesh2DTopology):
        """
        Creates a 2D triangular mesh with horizontal faces numbered first then
        vertical faces, then diagonal faces.  Vertices are numbered starting
        with the vertices at the corners of boxes and then the vertices at the
        centers of boxes.  Cells on the right of boxes are numbered first, then
        cells on the top of boxes, then cells on the left of boxes, then cells
        on the bottom of boxes.  Within each of the 'sub-categories' in the
        above, the vertices, cells and faces are numbered in the usual way.

        :Parameters:
          - `dx, dy`: The X and Y dimensions of each 'box'.
            If `dx` <> `dy`, the line segments connecting the cell
            centers will not be orthogonal to the faces.
          - `nx, ny`: The number of boxes in the X direction and the Y direction.
            The total number of boxes will be equal to `nx * ny`, and the total
            number of cells will be equal to `4 * nx * ny`.
        """

        self.args = {
            'dx': dx,
            'dy': dy,
            'nx': nx,
            'ny': ny
        }

        self.nx = nx
        self.ny = ny

        self.numberOfHorizontalFaces   = self.nx * (self.ny + 1)
        self.numberOfVerticalFaces     = self.ny * (self.nx + 1)
        self.numberOfEachDiagonalFaces = self.nx * self.ny

        self.dx  = PhysicalField(value = dx)
        scale    = PhysicalField(value = 1, unit = self.dx.unit)
        self.dx /= scale

        self.dy = PhysicalField(value = dy)
        if self.dy.unit.isDimensionless():
            self.dy = dy
        else:
            self.dy /= scale

        self.numberOfCornerVertices = (self.nx + 1) * (self. ny + 1)
        self.numberOfCenterVertices = self.nx * self.ny
        self.numberOfTotalVertices  = self.numberOfCornerVertices + self.numberOfCenterVertices

        self.offset = (0, 0)

        vertices = self._createVertices()
        faces    = self._createFaces()

        cells = self._createCells()
        cells = numerix.sort(cells, axis=0)

        Mesh2D.__init__(self, vertices, faces, cells,
                        _RepresentationClass=_RepresentationClass, _TopologyClass=_TopologyClass)

        self.scale = scale
 def _calcValue(self):
     l = len(self.distribution)
     bins = self.mesh.cellCenters[0]
     n = numerix.searchsorted(numerix.sort(self.distribution), bins)
     n = numerix.concatenate([n, [l]])
     dx = bins[1:] - bins[:-1]
     return (n[1:] - n[:-1]) / numerix.concatenate([dx, [dx[-1]]]) / float(l)
Ejemplo n.º 3
0
    def __init__(self, dx = 1., dy = 1., nx = 1, ny = 1,
                 _RepresentationClass=_Grid2DRepresentation, _TopologyClass=_Mesh2DTopology):
        """
        Creates a 2D triangular mesh with horizontal faces numbered first then
        vertical faces, then diagonal faces.  Vertices are numbered starting
        with the vertices at the corners of boxes and then the vertices at the
        centers of boxes.  Cells on the right of boxes are numbered first, then
        cells on the top of boxes, then cells on the left of boxes, then cells
        on the bottom of boxes.  Within each of the 'sub-categories' in the
        above, the vertices, cells and faces are numbered in the usual way.

        :Parameters:
          - `dx, dy`: The X and Y dimensions of each 'box'.
            If `dx` <> `dy`, the line segments connecting the cell
            centers will not be orthogonal to the faces.
          - `nx, ny`: The number of boxes in the X direction and the Y direction.
            The total number of boxes will be equal to `nx * ny`, and the total
            number of cells will be equal to `4 * nx * ny`.
        """

        self.args = {
            'dx': dx,
            'dy': dy,
            'nx': nx,
            'ny': ny
        }

        self.nx = nx
        self.ny = ny

        self.numberOfHorizontalFaces   = self.nx * (self.ny + 1)
        self.numberOfVerticalFaces     = self.ny * (self.nx + 1)
        self.numberOfEachDiagonalFaces = self.nx * self.ny

        self.dx  = PhysicalField(value = dx)
        scale    = PhysicalField(value = 1, unit = self.dx.unit)
        self.dx /= scale

        self.dy = PhysicalField(value = dy)
        if self.dy.unit.isDimensionless():
            self.dy = dy
        else:
            self.dy /= scale

        self.numberOfCornerVertices = (self.nx + 1) * (self. ny + 1)
        self.numberOfCenterVertices = self.nx * self.ny
        self.numberOfTotalVertices  = self.numberOfCornerVertices + self.numberOfCenterVertices

        self.offset = (0, 0)

        vertices = self._createVertices()
        faces    = self._createFaces()

        cells = self._createCells()
        cells = numerix.sort(cells, axis=0)

        Mesh2D.__init__(self, vertices, faces, cells,
                        _RepresentationClass=_RepresentationClass, _TopologyClass=_TopologyClass)

        self.scale = scale
Ejemplo n.º 4
0
    def _calcBaseFaceVertexIDs(self):
        
        cellVertexIDs = self.cellVertexIDs
    ## compute the face vertex IDs.
        ### this assumes triangular grid
        #cellFaceVertexIDs = numerix.ones((self.dimensions, self.dimensions + 1, self.numCells))
        cellFaceVertexIDs = numerix.ones((self.dimensions,len(cellVertexIDs), self.numCells))
        cellFaceVertexIDs = -1 * cellFaceVertexIDs

        if (self.dimensions == 3):
            cellFaceVertexIDs[:, 0, :] = cellVertexIDs[:3]
            cellFaceVertexIDs[:, 1, :] = numerix.concatenate((cellVertexIDs[:2], cellVertexIDs[3:]), axis = 0)
            cellFaceVertexIDs[:, 2, :] = numerix.concatenate((cellVertexIDs[:1], cellVertexIDs[2:]), axis = 0)
            cellFaceVertexIDs[:, 3, :] = cellVertexIDs[1:]
        elif (self.dimensions == 2):#define face with vertex pairs
            ###This isn't very general.
            ###Would be nice to allow cells with different number of faces. 
            if len(cellVertexIDs)==3:
                cellFaceVertexIDs[:, 0, :] = cellVertexIDs[:2]
                cellFaceVertexIDs[:, 1, :] = numerix.concatenate((cellVertexIDs[2:], cellVertexIDs[:1]), axis = 0)
                cellFaceVertexIDs[:, 2, :] = cellVertexIDs[1:]
            elif len(cellVertexIDs)==4:
                cellFaceVertexIDs[:, 0, :] = cellVertexIDs[0:2]
                cellFaceVertexIDs[:, 1, :] = cellVertexIDs[1:3]
                cellFaceVertexIDs[:, 2, :] = cellVertexIDs[2:4]
                cellFaceVertexIDs[:, 3, :] = numerix.concatenate((cellVertexIDs[3:], cellVertexIDs[:1]), axis = 0)

        cellFaceVertexIDs = cellFaceVertexIDs[::-1]#reverses order of vertex pair

        #self.unsortedBaseIDs = numerix.reshape(cellFaceVertexIDs.swapaxes(1,2), 
        #                                       (self.dimensions, 
        #                                        self.numCells * (self.dimensions + 1)))
        
        self.unsortedBaseIDs = numerix.reshape(cellFaceVertexIDs.swapaxes(1,2), 
                                               (self.dimensions, 
                                                self.numCells * (len(cellVertexIDs))))
        cellFaceVertexIDs = numerix.sort(cellFaceVertexIDs, axis=0)
        baseFaceVertexIDs = numerix.reshape(cellFaceVertexIDs.swapaxes(1,2), 
                                            (self.dimensions, 
                                             self.numCells * (len(cellVertexIDs))))

        self.baseFaceVertexIDs = baseFaceVertexIDs       
        self.cellFaceVertexIDs = cellFaceVertexIDs
Ejemplo n.º 5
0
    def _getAddedMeshValues(self, other, resolution=1e-2):
        """Calculate the parameters to define a concatenation of `other` with `self`

        Parameters
        ----------
        other : ~fipy.meshes.mesh.Mesh
             The `Mesh` to concatenate with `self`
        resolution : float
            How close vertices have to be (relative to the smallest
            cell-to-cell distance in either mesh) to be considered the same

        Returns
        -------
        dict
            (`vertexCoords`, `faceVertexIDs`, `cellFaceIDs`) for the new mesh.
        """

        selfc = self._concatenableMesh
        otherc = other._concatenableMesh

        selfNumFaces = selfc.faceVertexIDs.shape[-1]
        selfNumVertices = selfc.vertexCoords.shape[-1]
        otherNumFaces = otherc.faceVertexIDs.shape[-1]
        otherNumVertices = otherc.vertexCoords.shape[-1]
        ## check dimensions
        if(selfc.vertexCoords.shape[0] != otherc.vertexCoords.shape[0]):
            raise MeshAdditionError("Dimensions do not match")

        ## compute vertex correlates

#         from fipy.tools.debug import PRINT
#         PRINT("selfNumFaces", selfNumFaces)
#         PRINT("otherNumFaces", otherNumVertices)
#         PRINT("selfNumVertices", selfNumVertices)
#         PRINT("otherNumVertices", otherNumVertices)
# 
#         from fipy.tools.debug import PRINT
#         from fipy.tools.debug import PRINT
#         PRINT("otherExt", otherc.exteriorFaces.value)
#         raw_input()
#         PRINT("selfExt", selfc.exteriorFaces.value)
# 
#         PRINT("self filled", selfc.faceVertexIDs.filled())
#         PRINT("othe filled", otherc.faceVertexIDs.filled())
#         raw_input()
# 
#         PRINT("selfc.faceVertexIDs.filled()\n",selfc.faceVertexIDs.filled())
#         PRINT("flat\n",selfc.faceVertexIDs.filled()[...,
#             selfc.exteriorFaces.value].flatten())
#         PRINT("selfc.exteriorFaces.value\n",selfc.exteriorFaces.value)
#         PRINT("extfaces type", type(selfc.exteriorFaces))
#         PRINT("extfaces mesh", selfc.exteriorFaces.mesh)

        ## only try to match along the operation manifold
        if hasattr(self, "opManifold"):
            self_faces = self.opManifold(selfc)
        else:
            self_faces = selfc.exteriorFaces.value
        if hasattr(other, "opManifold"):
            other_faces = other.opManifold(otherc)
        else:
            other_faces = otherc.exteriorFaces.value

        ## only try to match exterior (X) vertices
        self_Xvertices = numerix.unique(selfc.faceVertexIDs.filled()[...,
            self_faces].flatten())
        other_Xvertices = numerix.unique(otherc.faceVertexIDs.filled()[...,
            other_faces].flatten())

        self_XvertexCoords = selfc.vertexCoords[..., self_Xvertices]
        other_XvertexCoords = otherc.vertexCoords[..., other_Xvertices]

        closest = numerix.nearest(self_XvertexCoords, other_XvertexCoords)

        # just because they're closest, doesn't mean they're close
        tmp = self_XvertexCoords[..., closest] - other_XvertexCoords
        distance = numerix.sqrtDot(tmp, tmp)
        # only want vertex pairs that are 100x closer than the smallest
        # cell-to-cell distance
        close = distance < resolution * min(selfc._cellToCellDistances.min(),
                                            otherc._cellToCellDistances.min())
        vertexCorrelates = numerix.array((self_Xvertices[closest[close]],
                                          other_Xvertices[close]))

        # warn if meshes don't touch, but allow it
        if (selfc._numberOfVertices > 0
            and otherc._numberOfVertices > 0
            and vertexCorrelates.shape[-1] == 0):
            import warnings
            warnings.warn("Vertices are not aligned", UserWarning, stacklevel=4)

        ## compute face correlates

        # ensure that both sets of faceVertexIDs have the same maximum number of (masked) elements
        self_faceVertexIDs = selfc.faceVertexIDs
        other_faceVertexIDs = otherc.faceVertexIDs

        diff = self_faceVertexIDs.shape[0] - other_faceVertexIDs.shape[0]
        if diff > 0:
            other_faceVertexIDs = numerix.append(other_faceVertexIDs,
                                                 -1 * numerix.ones((diff,)
                                                                   + other_faceVertexIDs.shape[1:], 'l'),
                                                 axis=0)
            other_faceVertexIDs = MA.masked_values(other_faceVertexIDs, -1)
        elif diff < 0:
            self_faceVertexIDs = numerix.append(self_faceVertexIDs,
                                                -1 * numerix.ones((-diff,)
                                                                  + self_faceVertexIDs.shape[1:], 'l'),
                                                axis=0)
            self_faceVertexIDs = MA.masked_values(self_faceVertexIDs, -1)

        # want self's Faces for which all faceVertexIDs are in vertexCorrelates
        self_matchingFaces = numerix.in1d(self_faceVertexIDs,
                                          vertexCorrelates[0]).reshape(self_faceVertexIDs.shape).all(axis=0).nonzero()[0]

        # want other's Faces for which all faceVertexIDs are in vertexCorrelates
        other_matchingFaces = numerix.in1d(other_faceVertexIDs,
                                           vertexCorrelates[1]).reshape(other_faceVertexIDs.shape).all(axis=0).nonzero()[0]

        # map other's Vertex IDs to new Vertex IDs,
        # accounting for overlaps with self's Vertex IDs
        vertex_map = numerix.empty(otherNumVertices, dtype=numerix.INT_DTYPE)
        verticesToAdd = numerix.delete(numerix.arange(otherNumVertices), vertexCorrelates[1])
        vertex_map[verticesToAdd] = numerix.arange(otherNumVertices - len(vertexCorrelates[1])) + selfNumVertices
        vertex_map[vertexCorrelates[1]] = vertexCorrelates[0]

        # calculate hashes of faceVertexIDs for comparing Faces

        if self_matchingFaces.shape[-1] == 0:
            self_faceHash = numerix.empty(self_matchingFaces.shape[:-1] + (0,), dtype="str")
        else:
            # sort each of self's Face's vertexIDs for canonical comparison
            self_faceHash = numerix.sort(self_faceVertexIDs[..., self_matchingFaces], axis=0)
            # then hash the Faces for comparison (NumPy set operations are only for 1D arrays)
            self_faceHash = numerix.apply_along_axis(str, axis=0, arr=self_faceHash)

        face_sort = numerix.argsort(self_faceHash)
        self_faceHash = self_faceHash[face_sort]
        self_matchingFaces = self_matchingFaces[face_sort]

        if other_matchingFaces.shape[-1] == 0:
            other_faceHash = numerix.empty(other_matchingFaces.shape[:-1] + (0,), dtype="str")
        else:
            # convert each of other's Face's vertexIDs to new IDs
            other_faceHash = vertex_map[other_faceVertexIDs[..., other_matchingFaces]]
            # sort each of other's Face's vertexIDs for canonical comparison
            other_faceHash = numerix.sort(other_faceHash, axis=0)
            # then hash the Faces for comparison (NumPy set operations are only for 1D arrays)
            other_faceHash = numerix.apply_along_axis(str, axis=0, arr=other_faceHash)

        face_sort = numerix.argsort(other_faceHash)
        other_faceHash = other_faceHash[face_sort]
        other_matchingFaces = other_matchingFaces[face_sort]

        self_matchingFaces = self_matchingFaces[numerix.in1d(self_faceHash,
                                                             other_faceHash)]
        other_matchingFaces = other_matchingFaces[numerix.in1d(other_faceHash,
                                                               self_faceHash)]

        faceCorrelates = numerix.array((self_matchingFaces,
                                        other_matchingFaces))

        # warn if meshes don't touch, but allow it
        if (selfc.numberOfFaces > 0
            and otherc.numberOfFaces > 0
            and faceCorrelates.shape[-1] == 0):
            import warnings
            warnings.warn("Faces are not aligned", UserWarning, stacklevel=4)

        # map other's Face IDs to new Face IDs,
        # accounting for overlaps with self's Face IDs
        face_map = numerix.empty(otherNumFaces, dtype=numerix.INT_DTYPE)
        facesToAdd = numerix.delete(numerix.arange(otherNumFaces), faceCorrelates[1])
        face_map[facesToAdd] = numerix.arange(otherNumFaces - len(faceCorrelates[1])) + selfNumFaces
        face_map[faceCorrelates[1]] = faceCorrelates[0]

        other_faceVertexIDs = vertex_map[otherc.faceVertexIDs[..., facesToAdd]]

        # ensure that both sets of cellFaceIDs have the same maximum number of (masked) elements
        self_cellFaceIDs = selfc.cellFaceIDs
        other_cellFaceIDs = face_map[otherc.cellFaceIDs]
        diff = self_cellFaceIDs.shape[0] - other_cellFaceIDs.shape[0]
        if diff > 0:
            other_cellFaceIDs = numerix.append(other_cellFaceIDs,
                                               -1 * numerix.ones((diff,)
                                                                 + other_cellFaceIDs.shape[1:], 'l'),
                                               axis=0)
            other_cellFaceIDs = MA.masked_values(other_cellFaceIDs, -1)
        elif diff < 0:
            self_cellFaceIDs = numerix.append(self_cellFaceIDs,
                                              -1 * numerix.ones((-diff,)
                                                                + self_cellFaceIDs.shape[1:], 'l'),
                                              axis=0)
            self_cellFaceIDs = MA.masked_values(self_cellFaceIDs, -1)

        # concatenate everything and return
        return {
            'vertexCoords': numerix.concatenate((selfc.vertexCoords,
                                                 otherc.vertexCoords[..., verticesToAdd]), axis=1),
            'faceVertexIDs': numerix.concatenate((self_faceVertexIDs,
                                                  other_faceVertexIDs), axis=1),
            'cellFaceIDs': MA.concatenate((self_cellFaceIDs,
                                           other_cellFaceIDs), axis=1)
            }
Ejemplo n.º 6
0
 def _nodesPerFace(self):
     return numerix.sort(self._unsortedNodesPerFace, axis=0)[::-1]
Ejemplo n.º 7
0
    def _getAddedMeshValues(self, other, resolution=1e-2):
        """Calculate the parameters to define a concatenation of `other` with `self`
        
        :Parameters:
          - `other`: The :class:`~fipy.meshes.numMesh.Mesh` to concatenate with `self`
          - `resolution`: How close vertices have to be (relative to the smallest 
            cell-to-cell distance in either mesh) to be considered the same

        :Returns:
          A `dict` with 3 elements: the new mesh vertexCoords, faceVertexIDs, and cellFaceIDs.
        """
        
        selfc = self._getConcatenableMesh()
        other = other._getConcatenableMesh()

        selfNumFaces = selfc.faceVertexIDs.shape[-1]
        selfNumVertices = selfc.vertexCoords.shape[-1]
        otherNumFaces = other.faceVertexIDs.shape[-1]
        otherNumVertices = other.vertexCoords.shape[-1]
        ## check dimensions
        if(selfc.vertexCoords.shape[0] != other.vertexCoords.shape[0]):
            raise MeshAdditionError, "Dimensions do not match"
            
        ## compute vertex correlates

        ## only try to match exterior (X) vertices
        self_Xvertices = numerix.unique(selfc._getFaceVertexIDs().filled()[..., selfc.getExteriorFaces().getValue()].flatten())
        other_Xvertices = numerix.unique(other._getFaceVertexIDs().filled()[..., other.getExteriorFaces().getValue()].flatten())

        self_XvertexCoords = selfc.vertexCoords[..., self_Xvertices]
        other_XvertexCoords = other.vertexCoords[..., other_Xvertices]
        
        # lifted from Mesh._getNearestCellID()
        other_vertexCoordMap = numerix.resize(other_XvertexCoords, 
                                              (self_XvertexCoords.shape[-1], 
                                               other_XvertexCoords.shape[0], 
                                               other_XvertexCoords.shape[-1])).swapaxes(0,1)
        tmp = self_XvertexCoords[..., numerix.newaxis] - other_vertexCoordMap
        closest = numerix.argmin(numerix.dot(tmp, tmp), axis=0)
        
        # just because they're closest, doesn't mean they're close
        tmp = self_XvertexCoords[..., closest] - other_XvertexCoords
        distance = numerix.sqrtDot(tmp, tmp)
        # only want vertex pairs that are 100x closer than the smallest 
        # cell-to-cell distance
        close = distance < resolution * min(selfc._getCellToCellDistances().min(), 
                                            other._getCellToCellDistances().min())
        vertexCorrelates = numerix.array((self_Xvertices[closest[close]],
                                          other_Xvertices[close]))
        
        # warn if meshes don't touch, but allow it
        if (selfc._getNumberOfVertices() > 0 
            and other._getNumberOfVertices() > 0 
            and vertexCorrelates.shape[-1] == 0):
            import warnings
            warnings.warn("Vertices are not aligned", UserWarning, stacklevel=4)

        ## compute face correlates

        # ensure that both sets of faceVertexIDs have the same maximum number of (masked) elements
        self_faceVertexIDs = selfc.faceVertexIDs
        other_faceVertexIDs = other.faceVertexIDs

        diff = self_faceVertexIDs.shape[0] - other_faceVertexIDs.shape[0]
        if diff > 0:
            other_faceVertexIDs = numerix.append(other_faceVertexIDs, 
                                                 -1 * numerix.ones((diff,) 
                                                                   + other_faceVertexIDs.shape[1:]),
                                                 axis=0)
            other_faceVertexIDs = MA.masked_values(other_faceVertexIDs, -1)
        elif diff < 0:
            self_faceVertexIDs = numerix.append(self_faceVertexIDs, 
                                                -1 * numerix.ones((-diff,) 
                                                                  + self_faceVertexIDs.shape[1:]),
                                                axis=0)
            self_faceVertexIDs = MA.masked_values(self_faceVertexIDs, -1)

        # want self's Faces for which all faceVertexIDs are in vertexCorrelates
        self_matchingFaces = numerix.in1d(self_faceVertexIDs, 
                                          vertexCorrelates[0]).reshape(self_faceVertexIDs.shape).all(axis=0).nonzero()[0]

        # want other's Faces for which all faceVertexIDs are in vertexCorrelates
        other_matchingFaces = numerix.in1d(other_faceVertexIDs, 
                                           vertexCorrelates[1]).reshape(other_faceVertexIDs.shape).all(axis=0).nonzero()[0]
                                           
        # map other's Vertex IDs to new Vertex IDs, 
        # accounting for overlaps with self's Vertex IDs
        vertex_map = numerix.empty(otherNumVertices, dtype=int)
        verticesToAdd = numerix.delete(numerix.arange(otherNumVertices), vertexCorrelates[1])
        vertex_map[verticesToAdd] = numerix.arange(otherNumVertices - len(vertexCorrelates[1])) + selfNumVertices
        vertex_map[vertexCorrelates[1]] = vertexCorrelates[0]

        # calculate hashes of faceVertexIDs for comparing Faces
        
        if self_matchingFaces.shape[-1] == 0:
            self_faceHash = numerix.empty(self_matchingFaces.shape[:-1] + (0,), dtype="str")
        else:
            # sort each of self's Face's vertexIDs for canonical comparison
            self_faceHash = numerix.sort(self_faceVertexIDs[..., self_matchingFaces], axis=0)
            # then hash the Faces for comparison (NumPy set operations are only for 1D arrays)
            self_faceHash = numerix.apply_along_axis(str, axis=0, arr=self_faceHash)
            
        face_sort = numerix.argsort(self_faceHash)
        self_faceHash = self_faceHash[face_sort]
        self_matchingFaces = self_matchingFaces[face_sort]

        if other_matchingFaces.shape[-1] == 0:
            other_faceHash = numerix.empty(other_matchingFaces.shape[:-1] + (0,), dtype="str")
        else:
            # convert each of other's Face's vertexIDs to new IDs
            other_faceHash = vertex_map[other_faceVertexIDs[..., other_matchingFaces]]
            # sort each of other's Face's vertexIDs for canonical comparison
            other_faceHash = numerix.sort(other_faceHash, axis=0)
            # then hash the Faces for comparison (NumPy set operations are only for 1D arrays)
            other_faceHash = numerix.apply_along_axis(str, axis=0, arr=other_faceHash)

        face_sort = numerix.argsort(other_faceHash)
        other_faceHash = other_faceHash[face_sort]
        other_matchingFaces = other_matchingFaces[face_sort]

        self_matchingFaces = self_matchingFaces[numerix.in1d(self_faceHash, 
                                                             other_faceHash)]
        other_matchingFaces = other_matchingFaces[numerix.in1d(other_faceHash, 
                                                               self_faceHash)]
        
        faceCorrelates = numerix.array((self_matchingFaces,
                                        other_matchingFaces))

        # warn if meshes don't touch, but allow it
        if (selfc._getNumberOfFaces() > 0 
            and other._getNumberOfFaces() > 0 
            and faceCorrelates.shape[-1] == 0):
            import warnings
            warnings.warn("Faces are not aligned", UserWarning, stacklevel=4)

        # map other's Face IDs to new Face IDs, 
        # accounting for overlaps with self's Face IDs
        face_map = numerix.empty(otherNumFaces, dtype=int)
        facesToAdd = numerix.delete(numerix.arange(otherNumFaces), faceCorrelates[1])
        face_map[facesToAdd] = numerix.arange(otherNumFaces - len(faceCorrelates[1])) + selfNumFaces
        face_map[faceCorrelates[1]] = faceCorrelates[0]
        
        other_faceVertexIDs = vertex_map[other.faceVertexIDs[..., facesToAdd]]
        
        # ensure that both sets of cellFaceIDs have the same maximum number of (masked) elements
        self_cellFaceIDs = selfc.cellFaceIDs
        other_cellFaceIDs = face_map[other.cellFaceIDs]
        diff = self_cellFaceIDs.shape[0] - other_cellFaceIDs.shape[0]
        if diff > 0:
            other_cellFaceIDs = numerix.append(other_cellFaceIDs, 
                                               -1 * numerix.ones((diff,) 
                                                                 + other_cellFaceIDs.shape[1:]),
                                               axis=0)
            other_cellFaceIDs = MA.masked_values(other_cellFaceIDs, -1)
        elif diff < 0:
            self_cellFaceIDs = numerix.append(self_cellFaceIDs, 
                                              -1 * numerix.ones((-diff,) 
                                                                + self_cellFaceIDs.shape[1:]),
                                              axis=0)
            self_cellFaceIDs = MA.masked_values(self_cellFaceIDs, -1)

        # concatenate everything and return
        return {
            'vertexCoords': numerix.concatenate((selfc.vertexCoords, 
                                                 other.vertexCoords[..., verticesToAdd]), axis=1), 
            'faceVertexIDs': numerix.concatenate((self_faceVertexIDs, 
                                                  other_faceVertexIDs), axis=1), 
            'cellFaceIDs': MA.concatenate((self_cellFaceIDs, 
                                           other_cellFaceIDs), axis=1)
            }
Ejemplo n.º 8
0
 def _nodesPerFace(self):
     return numerix.sort(self._unsortedNodesPerFace, axis=0)[::-1]