Пример #1
0
 def deleteIslands(self):
     cellToCellIDs = self.mesh._cellToCellIDs
     adjVals = numerix.take(self.value, cellToCellIDs)
     adjInterfaceValues = MA.masked_array(adjVals, mask = (adjVals * self.value) > 0)
     masksum = numerix.sum(numerix.logical_not(MA.getmask(adjInterfaceValues)), 0)
     tmp = MA.logical_and(masksum == 4, self.value > 0)
     self.value = numerix.array(MA.where(tmp, -1, self.value))
Пример #2
0
    def _calcValue(self):

        Nfaces = self.mesh.numberOfFaces
        M = self.mesh._maxFacesPerCell
        dim = self.mesh.dim
        cellFaceIDs = self.mesh.cellFaceIDs

        faceNormalAreas = self.distanceVar._levelSetNormals * self.mesh._faceAreas

        cellFaceNormalAreas = numerix.array(MA.filled(numerix.take(faceNormalAreas, cellFaceIDs, axis=-1), 0))
        norms = numerix.array(MA.filled(MA.array(self.mesh._cellNormals), 0))

        alpha = numerix.dot(cellFaceNormalAreas, norms)
        alpha = numerix.where(alpha > 0, alpha, 0)

        alphasum = numerix.sum(alpha, axis=0)
        alphasum += (alphasum < 1e-100) * 1.0
        alpha = alpha / alphasum

        phi = numerix.repeat(self.distanceVar[numerix.newaxis, ...], M, axis=0)
        alpha = numerix.where(phi > 0., 0, alpha)

        volumes = numerix.array(self.mesh.cellVolumes)
        alpha = alpha * volumes * norms

        value = numerix.zeros((dim, Nfaces), 'd')

        vector._putAdd(value, cellFaceIDs, alpha, mask=MA.getmask(MA.array(cellFaceIDs)))

##         value = numerix.reshape(value, (dim, Nfaces, dim))

        return -value / self.mesh._faceAreas
Пример #3
0
    def _buildMatrix(self, var, SparseMatrix, boundaryCondtions=(), dt=None, equation=None):

        oldArray = var.getOld()

        mesh = var.getMesh()
        NCells = mesh.getNumberOfCells()
        NCellFaces = mesh._getMaxFacesPerCell()

        cellValues = numerix.repeat(oldArray[numerix.newaxis, ...], NCellFaces, axis = 0)
        
        cellIDs = numerix.repeat(numerix.arange(NCells)[numerix.newaxis, ...], NCellFaces, axis = 0)
        cellToCellIDs = mesh._getCellToCellIDs()

        if NCells > 0:
            cellToCellIDs = MA.where(MA.getmask(cellToCellIDs), cellIDs, cellToCellIDs) 

            adjacentValues = numerix.take(oldArray, cellToCellIDs)

            differences = self._getDifferences(adjacentValues, cellValues, oldArray, cellToCellIDs, mesh)
            differences = MA.filled(differences, 0)
            
            minsq = numerix.sqrt(numerix.sum(numerix.minimum(differences, numerix.zeros((NCellFaces, NCells)))**2, axis=0))
            maxsq = numerix.sqrt(numerix.sum(numerix.maximum(differences, numerix.zeros((NCellFaces, NCells)))**2, axis=0))

            coeff = numerix.array(self._getGeomCoeff(mesh))

            coeffXdiffereneces = coeff * ((coeff > 0.) * minsq + (coeff < 0.) * maxsq)
        else:
            coeffXdiffereneces = 0.

        return (SparseMatrix(mesh=var.getMesh()), -coeffXdiffereneces * mesh.getCellVolumes())
Пример #4
0
    def _getDifferences(self, adjacentValues, cellValues, oldArray, cellToCellIDs, mesh):

        dAP = mesh._cellToCellDistances

##        adjacentGradient = numerix.take(oldArray.grad, cellToCellIDs)
        adjacentGradient = numerix.take(oldArray.grad, mesh._cellToCellIDs, axis=-1)
        adjacentNormalGradient = numerix.dot(adjacentGradient, mesh._cellNormals)
        adjacentUpValues = cellValues + 2 * dAP * adjacentNormalGradient

        cellIDs = numerix.repeat(numerix.arange(mesh.numberOfCells)[numerix.newaxis, ...],
                mesh._maxFacesPerCell, axis=0)
        cellIDs = MA.masked_array(cellIDs, mask = MA.getmask(mesh._cellToCellIDs))
        cellGradient = numerix.take(oldArray.grad, cellIDs, axis=-1)
        cellNormalGradient = numerix.dot(cellGradient, mesh._cellNormals)
        cellUpValues = adjacentValues - 2 * dAP * cellNormalGradient

        cellLaplacian = (cellUpValues + adjacentValues - 2 * cellValues) / dAP**2

        adjacentLaplacian = (adjacentUpValues + cellValues - 2 * adjacentValues) / dAP**2
        adjacentLaplacian = adjacentLaplacian.filled(0)
        cellLaplacian = cellLaplacian.filled(0)

        mm = numerix.where(cellLaplacian * adjacentLaplacian < 0.,
                           0.,
                           numerix.where(abs(cellLaplacian) > abs(adjacentLaplacian),
                                         adjacentLaplacian,
                                         cellLaplacian))

        return FirstOrderAdvectionTerm._getDifferences(self, adjacentValues, cellValues, oldArray, cellToCellIDs, mesh) -  mm * dAP / 2.
Пример #5
0
 def _calcInteriorAndExteriorFaceIDs(self):
     from fipy.variables.faceVariable import FaceVariable
     mask = MA.getmask(self.faceCellIDs[1])
     exteriorFaces = FaceVariable(mesh=self, value=mask)
     interiorFaces = FaceVariable(mesh=self,
                                  value=numerix.logical_not(mask))
     return interiorFaces, exteriorFaces
Пример #6
0
Файл: mesh.py Проект: regmi/fipy
 def _calcInteriorAndExteriorFaceIDs(self):
     from fipy.variables.faceVariable import FaceVariable
     mask = MA.getmask(self.faceCellIDs[1])
     self.exteriorFaces = FaceVariable(mesh=self, 
                                       value=mask)
     self.interiorFaces = FaceVariable(mesh=self, 
                                       value=numerix.logical_not(mask))
Пример #7
0
    def _buildMatrix(self, var, SparseMatrix, boundaryConditions=(), dt=None, equation=None, transientGeomCoeff=None, diffusionGeomCoeff=None):

        oldArray = var.old

        mesh = var.mesh
        NCells = mesh.numberOfCells
        NCellFaces = mesh._maxFacesPerCell

        cellValues = numerix.repeat(oldArray[numerix.newaxis, ...], NCellFaces, axis = 0)

        cellIDs = numerix.repeat(numerix.arange(NCells)[numerix.newaxis, ...], NCellFaces, axis = 0)
        cellToCellIDs = mesh._cellToCellIDs

        if NCells > 0:
            cellToCellIDs = MA.where(MA.getmask(cellToCellIDs), cellIDs, cellToCellIDs) 

            adjacentValues = numerix.take(oldArray, cellToCellIDs)

            differences = self._getDifferences(adjacentValues, cellValues, oldArray, cellToCellIDs, mesh)
            differences = MA.filled(differences, 0)

            minsq = numerix.sqrt(numerix.sum(numerix.minimum(differences, numerix.zeros((NCellFaces, NCells), 'l'))**2, axis=0))
            maxsq = numerix.sqrt(numerix.sum(numerix.maximum(differences, numerix.zeros((NCellFaces, NCells), 'l'))**2, axis=0))

            coeff = numerix.array(self._getGeomCoeff(var))

            coeffXdiffereneces = coeff * ((coeff > 0.) * minsq + (coeff < 0.) * maxsq)
        else:
            coeffXdiffereneces = 0.

        return (var, SparseMatrix(mesh=var.mesh), -coeffXdiffereneces * mesh.cellVolumes)
Пример #8
0
    def _buildMatrix(self, var, SparseMatrix, boundaryConditions=(), dt=None, equation=None, transientGeomCoeff=None, diffusionGeomCoeff=None):

        oldArray = var.old

        mesh = var.mesh
        NCells = mesh.numberOfCells
        NCellFaces = mesh._maxFacesPerCell

        cellValues = numerix.repeat(oldArray[numerix.newaxis, ...], NCellFaces, axis = 0)

        cellIDs = numerix.repeat(numerix.arange(NCells)[numerix.newaxis, ...], NCellFaces, axis = 0)
        cellToCellIDs = mesh._cellToCellIDs

        if NCells > 0:
            cellToCellIDs = MA.where(MA.getmask(cellToCellIDs), cellIDs, cellToCellIDs)

            adjacentValues = numerix.take(oldArray, cellToCellIDs)

            differences = self._getDifferences(adjacentValues, cellValues, oldArray, cellToCellIDs, mesh)
            differences = MA.filled(differences, 0)

            minsq = numerix.sqrt(numerix.sum(numerix.minimum(differences, numerix.zeros((NCellFaces, NCells), 'l'))**2, axis=0))
            maxsq = numerix.sqrt(numerix.sum(numerix.maximum(differences, numerix.zeros((NCellFaces, NCells), 'l'))**2, axis=0))

            coeff = numerix.array(self._getGeomCoeff(var))

            coeffXdifferences = coeff * ((coeff > 0.) * minsq + (coeff < 0.) * maxsq)
        else:
            coeffXdifferences = 0.

        return (var, SparseMatrix(mesh=var.mesh), -coeffXdifferences * mesh.cellVolumes)
Пример #9
0
    def _calcFaceCenters(self):
        maskedFaceVertexIDs = MA.filled(self.faceVertexIDs, 0)

        faceVertexCoords = numerix.take(self.vertexCoords, maskedFaceVertexIDs, axis=1)

        if MA.getmask(self.faceVertexIDs) is False:
            faceVertexCoordsMask = numerix.zeros(numerix.shape(faceVertexCoords), 'l')
        else:
            faceVertexCoordsMask = \
              numerix.repeat(MA.getmaskarray(self.faceVertexIDs)[numerix.newaxis,...], 
                             self.dim, axis=0)
            
        faceVertexCoords = MA.array(data=faceVertexCoords, mask=faceVertexCoordsMask)

        return MA.filled(MA.average(faceVertexCoords, axis=1))
Пример #10
0
    def _getDifferences(self, adjacentValues, cellValues, oldArray,
                        cellToCellIDs, mesh):

        dAP = mesh._cellToCellDistances

        ##        adjacentGradient = numerix.take(oldArray.grad, cellToCellIDs)
        adjacentGradient = numerix.take(oldArray.grad,
                                        mesh._cellToCellIDs,
                                        axis=-1)
        adjacentNormalGradient = numerix.dot(adjacentGradient,
                                             mesh._cellNormals)
        adjacentUpValues = cellValues + 2 * dAP * adjacentNormalGradient

        cellIDs = numerix.repeat(numerix.arange(
            mesh.numberOfCells)[numerix.newaxis, ...],
                                 mesh._maxFacesPerCell,
                                 axis=0)
        cellIDs = MA.masked_array(cellIDs,
                                  mask=MA.getmask(mesh._cellToCellIDs))
        cellGradient = numerix.take(oldArray.grad, cellIDs, axis=-1)
        cellNormalGradient = numerix.dot(cellGradient, mesh._cellNormals)
        cellUpValues = adjacentValues - 2 * dAP * cellNormalGradient

        cellLaplacian = (cellUpValues + adjacentValues -
                         2 * cellValues) / dAP**2

        adjacentLaplacian = (adjacentUpValues + cellValues -
                             2 * adjacentValues) / dAP**2
        adjacentLaplacian = adjacentLaplacian.filled(0)
        cellLaplacian = cellLaplacian.filled(0)

        mm = numerix.where(
            cellLaplacian * adjacentLaplacian < 0., 0.,
            numerix.where(
                abs(cellLaplacian) > abs(adjacentLaplacian), adjacentLaplacian,
                cellLaplacian))

        return FirstOrderAdvectionTerm._getDifferences(
            self, adjacentValues, cellValues, oldArray, cellToCellIDs,
            mesh) - mm * dAP / 2.
Пример #11
0
    def _calcFaceCellIDs(self):
        array = MA.array(MA.indices(self.cellFaceIDs.shape, 'l')[1],
                         mask=MA.getmask(self.cellFaceIDs))
        faceCellIDs = MA.zeros((2, self.numberOfFaces), 'l')

        ## Nasty bug: MA.put(arr, ids, values) fills its ids and
        ## values arguments when masked!  This was not the behavior
        ## that was assumed when used below.  It was only working
        ## because the old fill value was 0 and the first element of
        ## the array needed to be 0 since the cell's face was
        ## 0. numerix.put() has been changed to deal with this
        ## properly.

        ##         MA.put(firstRow, cellFaceIDsFlat[::-1], array[::-1])
        ##         MA.put(secondRow, cellFaceIDsFlat, array)
        firstRow = faceCellIDs[0]
        secondRow = faceCellIDs[1]

        numerix.put(firstRow, self.cellFaceIDs[::-1, ::-1], array[::-1, ::-1])
        numerix.put(secondRow, self.cellFaceIDs, array)

        mask = ((False, ) * self.numberOfFaces, (firstRow == secondRow))
        return MA.sort(MA.array(faceCellIDs, mask=mask), axis=0)
Пример #12
0
Файл: mesh.py Проект: regmi/fipy
    def _calcFaceCellIDs(self):
        array = MA.array(MA.indices(self.cellFaceIDs.shape, 'l')[1], 
                         mask=MA.getmask(self.cellFaceIDs))
        self.faceCellIDs = MA.zeros((2, self.numberOfFaces), 'l')

        ## Nasty bug: MA.put(arr, ids, values) fills its ids and
        ## values arguments when masked!  This was not the behavior
        ## that was assumed when used below.  It was only working
        ## because the old fill value was 0 and the first element of
        ## the array needed to be 0 since the cell's face was
        ## 0. numerix.put() has been changed to deal with this
        ## properly.

##         MA.put(firstRow, cellFaceIDsFlat[::-1], array[::-1])
##         MA.put(secondRow, cellFaceIDsFlat, array)
        firstRow = self.faceCellIDs[0]
        secondRow = self.faceCellIDs[1]
        numerix.put(firstRow, self.cellFaceIDs[::-1,::-1], array[::-1,::-1])
        numerix.put(secondRow, self.cellFaceIDs, array)
        
        mask = ((False,) * self.numberOfFaces, (firstRow == secondRow))
        self.faceCellIDs = MA.sort(MA.array(self.faceCellIDs, mask = mask),
                                   axis=0)
Пример #13
0
Файл: mesh.py Проект: regmi/fipy
    def _getAddedMeshValues(self, other, smallNumber):
        """
        Returns a `dictionary` with 3 elements: the new mesh vertexCoords, faceVertexIDs, and cellFaceIDs.
        """

        other = other._getConcatenableMesh()

        selfNumFaces = self.faceVertexIDs.shape[-1]
        selfNumVertices = self.vertexCoords.shape[-1]
        otherNumFaces = other.faceVertexIDs.shape[-1]
        otherNumVertices = other.vertexCoords.shape[-1]
        ## check dimensions
        if(self.vertexCoords.shape[0] != other.vertexCoords.shape[0]):
            raise MeshAdditionError, "Dimensions do not match"
        ## compute vertex correlates
        vertexCorrelates = {}
        for i in range(selfNumVertices):
            for j in range(otherNumVertices):
                diff = self.vertexCoords[...,i] - other.vertexCoords[...,j]
                diff = numerix.array(diff)
                if (sum(diff ** 2) < smallNumber):
                    vertexCorrelates[j] = i
        if (self._getNumberOfVertices() > 0 and other._getNumberOfVertices() > 0 and vertexCorrelates == {}):
            raise MeshAdditionError, "Vertices are not aligned"

        
         
        ## compute face correlates
        faceCorrelates = {}
        for i in range(otherNumFaces):
##          Seems to be overwriting other.faceVertexIDs with new numpy
##            currFace = other.faceVertexIDs[i]
##            currFace = other.faceVertexIDs[...,i].copy()
##          Changed this again as numpy 1.0.4 seems to have no copy method for
##          masked arrays.
            try:
                currFace = other.faceVertexIDs[...,i].copy()
            except:
                currFace = MA.array(other.faceVertexIDs[...,i], mask=MA.getmask(other.faceVertexIDs[...,i]))

            keepGoing = 1
            currIndex = 0 
            for item in currFace:
                if(vertexCorrelates.has_key(item)):
                    currFace[currIndex] = vertexCorrelates[item]
                    currIndex = currIndex + 1
                else:
                    keepGoing = 0
            if(keepGoing == 1):
                for j in range(selfNumFaces):
                    if (self._equalExceptOrder(currFace, self.faceVertexIDs[...,j])):
                        faceCorrelates[i] = j
        if (self._getNumberOfFaces() > 0 and other._getNumberOfFaces() > 0 and faceCorrelates == {}):
            raise MeshAdditionError, "Faces are not aligned"
        
        faceIndicesToAdd = ()
        for i in range(otherNumFaces):
            if(not faceCorrelates.has_key(i)):
                faceIndicesToAdd = faceIndicesToAdd + (i,)
        vertexIndicesToAdd = ()
        for i in range(otherNumVertices):
            if(not vertexCorrelates.has_key(i)):
                vertexIndicesToAdd = vertexIndicesToAdd + (i,)

        ##compute the full face and vertex correlation list
        a = selfNumFaces
        for i in faceIndicesToAdd:
            faceCorrelates[i] = a
            a = a + 1
        b = selfNumVertices
        for i in vertexIndicesToAdd:
            vertexCorrelates[i] = b
            b = b + 1

        ## compute what the cells are that we need to add
        cellsToAdd = numerix.ones((self.cellFaceIDs.shape[0], other.cellFaceIDs.shape[-1]))
        cellsToAdd = -1 * cellsToAdd

        for j in range(other.cellFaceIDs.shape[-1]):
            for i in range(other.cellFaceIDs.shape[0]):
                cellsToAdd[i, j] = faceCorrelates[other.cellFaceIDs[i, j]]

        cellsToAdd = MA.masked_values(cellsToAdd, -1)


        ## compute what the faces are that we need to add
        facesToAdd = numerix.take(other.faceVertexIDs, faceIndicesToAdd, axis=1)

        for j in range(facesToAdd.shape[-1]):
            for i in range(facesToAdd.shape[0]):
                facesToAdd[i, j] = vertexCorrelates[facesToAdd[i, j]]

        ## compute what the vertices are that we need to add
        verticesToAdd = numerix.take(other.vertexCoords, vertexIndicesToAdd, axis=1)

        return {
            'vertexCoords': numerix.concatenate((self.vertexCoords, verticesToAdd), axis=1), 
            'faceVertexIDs': numerix.concatenate((self.faceVertexIDs, facesToAdd), axis=1), 
            'cellFaceIDs': MA.concatenate((self.cellFaceIDs, cellsToAdd), axis=1)
            }
Пример #14
0
    def _calcDistanceFunction(self, extensionVariable = None, narrowBandWidth = None, deleteIslands = False):

        if narrowBandWidth == None:
            narrowBandWidth = self.narrowBandWidth

        ## calculate interface values

        cellToCellIDs = self.mesh._getCellToCellIDs()

        if deleteIslands:
            adjVals = numerix.take(self.value, cellToCellIDs)
            adjInterfaceValues = MA.masked_array(adjVals, mask = (adjVals * self.value) > 0)
            masksum = numerix.sum(numerix.logical_not(MA.getmask(adjInterfaceValues)), 0)
            tmp = MA.logical_and(masksum == 4, self.value > 0)
            self.value = MA.where(tmp, -1, self.value)

        adjVals = numerix.take(self.value, cellToCellIDs)
        adjInterfaceValues = MA.masked_array(adjVals, mask = (adjVals * self.value) > 0)
        dAP = self.mesh._getCellToCellDistances()
        distances = abs(self.value * dAP / (self.value - adjInterfaceValues))
        indices = MA.argsort(distances, 0)
        sign = (self.value > 0) * 2 - 1

        s = distances[indices[0], numerix.arange(indices.shape[1])]

        if self.mesh.getDim() == 2:

            t = distances[indices[1], numerix.arange(indices.shape[1])]
            u = distances[indices[2], numerix.arange(indices.shape[1])]

            if indices.shape[1] > 0:
                ns = self.cellNormals[..., indices[0], numerix.arange(indices.shape[1])]
                nt = self.cellNormals[..., indices[1], numerix.arange(indices.shape[1])]
            else:
                ns = MA.zeros(self.cellNormals.shape[:-1] + (0,))
                nt = MA.zeros(self.cellNormals.shape[:-1] + (0,))

            signedDistance = MA.where(MA.getmask(s),
                                      self.value,
                                      MA.where(MA.getmask(t),
                                               sign * s,
                                               MA.where(abs(numerix.dot(ns,nt)) < 0.9,
                                                        sign * s * t / MA.sqrt(s**2 + t**2),
                                                        MA.where(MA.getmask(u),
                                                                 sign * s,
                                                                 sign * s * u / MA.sqrt(s**2 + u**2)
                                                                 )
                                                        )
                                               )
                                      )
        else:
            signedDistance = MA.where(MA.getmask(s),
                                      self.value,
                                      sign * s)
            

        self.value = signedDistance

        ## calculate interface flag
        masksum = numerix.sum(numerix.logical_not(MA.getmask(distances)), 0)
        interfaceFlag = (masksum > 0).astype('l')

        ## spread the extensionVariable to the whole interface
        flag = True
        if extensionVariable is None:
            extensionVariable = numerix.zeros(self.mesh.getNumberOfCells(), 'd')
            flag = False
            
        ext = numerix.zeros(self.mesh.getNumberOfCells(), 'd')

        positiveInterfaceFlag = numerix.where(self.value > 0, interfaceFlag, 0)
        negativeInterfaceIDs = numerix.nonzero(numerix.where(self.value < 0, interfaceFlag, 0))[0]

        for id in negativeInterfaceIDs:
            tmp, extensionVariable[...,id] = self._calcTrialValue(id, positiveInterfaceFlag, extensionVariable)

        if flag:
            self.value = self.tmpValue.copy()

        ## evaluate the trialIDs
        adjInterfaceFlag = numerix.take(interfaceFlag, cellToCellIDs)
        hasAdjInterface = (numerix.sum(MA.filled(adjInterfaceFlag, 0), 0) > 0).astype('l')

        trialFlag = numerix.logical_and(numerix.logical_not(interfaceFlag), hasAdjInterface).astype('l')

        trialIDs = list(numerix.nonzero(trialFlag)[0])
        evaluatedFlag = interfaceFlag


        for id in trialIDs:
            self.value[...,id], extensionVariable[id] = self._calcTrialValue(id, evaluatedFlag, extensionVariable)

        while len(trialIDs):

            id = trialIDs[numerix.argmin(abs(numerix.take(self.value, trialIDs)))]

            if abs(self.value[...,id]) > narrowBandWidth / 2:
                break

            trialIDs.remove(id)
            evaluatedFlag[...,id] = 1


            for adjID in MA.filled(cellToCellIDs[...,id], -1):
                if adjID != -1:
                    if not evaluatedFlag[...,adjID]:
                        self.value[...,adjID], extensionVariable[...,adjID] = self._calcTrialValue(adjID, evaluatedFlag, extensionVariable)
                        if adjID not in trialIDs:
                            trialIDs.append(adjID)

        self.value = numerix.array(self.value)