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)
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)
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())
def _createVertices(self): x = self._calcVertexCoordinates(self.dx, self.nx) x = numerix.resize(x, (self.numberOfVertices,)) y = self._calcVertexCoordinates(self.dy, self.ny) y = numerix.repeat(y, self.numberOfVerticalColumns) y = numerix.resize(y, (self.numberOfVertices,)) z = self._calcVertexCoordinates(self.dz, self.nz) z = numerix.repeat(z, self.numberOfHorizontalRows * self.numberOfVerticalColumns) z = numerix.resize(z, (self.numberOfVertices,)) return numerix.array((x, y, z))
def _createVertices(self): x = numerix.arange(self.nx + 1) * self.dx y = numerix.arange(self.ny + 1) * self.dy x = numerix.resize(x, (self.numberOfCornerVertices, )) y = numerix.repeat(y, self.nx + 1) boxCorners = numerix.array((x, y)) x = numerix.arange(0.5, self.nx + 0.5) * self.dx y = numerix.arange(0.5, self.ny + 0.5) * self.dy x = numerix.resize(x, (self.numberOfCenterVertices, )) y = numerix.repeat(y, self.nx) boxCenters = numerix.array((x, y)) return numerix.concatenate((boxCorners, boxCenters), axis=1)
def createVertices(dx, dy, dz, nx, ny, nz, numVertices, numHorizRows, numVertCols): x = _AbstractGridBuilder.calcVertexCoordinates(dx, nx) x = numerix.resize(x, (numVertices,)) y = _AbstractGridBuilder.calcVertexCoordinates(dy, ny) y = numerix.repeat(y, numVertCols) y = numerix.resize(y, (numVertices,)) z = _AbstractGridBuilder.calcVertexCoordinates(dz, nz) z = numerix.repeat(z, numHorizRows * numVertCols) z = numerix.resize(z, (numVertices,)) return numerix.array((x, y, z))
def _calcFaceAreas(self): faceVertexIDs = MA.filled(self.faceVertexIDs, -1) substitute = numerix.repeat(faceVertexIDs[numerix.newaxis, 0], faceVertexIDs.shape[0], axis=0) faceVertexIDs = numerix.where(MA.getmaskarray(self.faceVertexIDs), substitute, faceVertexIDs) faceVertexCoords = numerix.take(self.vertexCoords, faceVertexIDs, axis=1) faceOrigins = numerix.repeat(faceVertexCoords[:,0], faceVertexIDs.shape[0], axis=0) faceOrigins = numerix.reshape(faceOrigins, MA.shape(faceVertexCoords)) faceVertexCoords = faceVertexCoords - faceOrigins left = range(faceVertexIDs.shape[0]) right = left[1:] + [left[0]] cross = numerix.sum(numerix.cross(faceVertexCoords, numerix.take(faceVertexCoords, right, 1), axis=0), 1) self.faceAreas = numerix.sqrtDot(cross, cross) / 2.
def _createVertices(self): x = numerix.arange(self.nx + 1) * self.dx y = numerix.arange(self.ny + 1) * self.dy x = numerix.resize(x, (self.numberOfCornerVertices,)) y = numerix.repeat(y, self.nx + 1) boxCorners = numerix.array((x, y)) x = numerix.arange(0.5, self.nx + 0.5) * self.dx y = numerix.arange(0.5, self.ny + 0.5) * self.dy x = numerix.resize(x, (self.numberOfCenterVertices,)) y = numerix.repeat(y, self.nx) boxCenters = numerix.array((x, y)) return numerix.concatenate((boxCorners, boxCenters), axis=1)
def createVertices(dx, dy, dz, nx, ny, nz, numVertices, numHorizRows, numVertCols): x = _AbstractGridBuilder.calcVertexCoordinates(dx, nx) x = numerix.resize(x, (numVertices, )) y = _AbstractGridBuilder.calcVertexCoordinates(dy, ny) y = numerix.repeat(y, numVertCols) y = numerix.resize(y, (numVertices, )) z = _AbstractGridBuilder.calcVertexCoordinates(dz, nz) z = numerix.repeat(z, numHorizRows * numVertCols) z = numerix.resize(z, (numVertices, )) return numerix.array((x, y, z))
def _cellDistances(self): Hdis = numerix.repeat((self.dy,), self.numberOfHorizontalFaces) Hdis = numerix.reshape(Hdis, (self.nx, self.numberOfHorizontalRows)) if self.numberOfHorizontalRows > 0: Hdis[..., 0] = self.dy / 2. Hdis[..., -1] = self.dy / 2. Vdis = numerix.repeat((self.dx,), self.numberOfFaces - self.numberOfHorizontalFaces) Vdis = numerix.reshape(Vdis, (self.numberOfVerticalColumns, self.ny)) if self.numberOfVerticalColumns > 0: Vdis[0, ...] = self.dx / 2. Vdis[-1, ...] = self.dx / 2. return numerix.concatenate((numerix.reshape(numerix.swapaxes(Hdis, 0, 1), (self.numberOfHorizontalFaces,)), numerix.reshape(numerix.swapaxes(Vdis, 0, 1), (self.numberOfFaces - self.numberOfHorizontalFaces,))))
def _cellInterfaceNormals(self): """ Returns the interface normals over the cells. >>> from fipy.meshes import Grid2D >>> from fipy.variables.cellVariable import CellVariable >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2) >>> distanceVariable = DistanceVariable(mesh = mesh, ... value = (-0.5, 0.5, 0.5, 1.5)) >>> v = 1 / numerix.sqrt(2) >>> answer = CellVariable(mesh=mesh, ... value=(((0, 0, v, 0), ... (0, 0, 0, 0), ... (0, 0, 0, 0), ... (0, v, 0, 0)), ... ((0, 0, v, 0), ... (0, 0, 0, 0), ... (0, 0, 0, 0), ... (0, v, 0, 0)))) >>> print(numerix.allclose(distanceVariable._cellInterfaceNormals, answer)) True """ dim = self.mesh.dim valueOverFaces = numerix.repeat(self._cellValueOverFaces[numerix.newaxis, ...], dim, axis=0) cellFaceIDs = self.mesh.cellFaceIDs if cellFaceIDs.shape[-1] > 0: interfaceNormals = self._interfaceNormals[..., cellFaceIDs] else: interfaceNormals = 0 return MA.where(valueOverFaces < 0, 0, interfaceNormals)
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.
def _cellValueOverFaces(self): """ Returns the cells values at the faces. >>> from fipy.meshes import Grid2D >>> from fipy.variables.cellVariable import CellVariable >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2) >>> distanceVariable = DistanceVariable(mesh = mesh, ... value = (-0.5, 0.5, 0.5, 1.5)) >>> answer = CellVariable(mesh=mesh, ... value=((-.5, .5, .5, 1.5), ... (-.5, .5, .5, 1.5), ... (-.5, .5, .5, 1.5), ... (-.5, .5, .5, 1.5))) >>> print numerix.allclose(distanceVariable._cellValueOverFaces, answer) True """ M = self.mesh._maxFacesPerCell N = self.mesh.numberOfCells return numerix.reshape( numerix.repeat(numerix.array(self._value)[numerix.newaxis, ...], M, axis=0), (M, N))
def _cellInterfaceNormals(self): """ Returns the interface normals over the cells. >>> from fipy.meshes import Grid2D >>> from fipy.variables.cellVariable import CellVariable >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2) >>> distanceVariable = DistanceVariable(mesh = mesh, ... value = (-0.5, 0.5, 0.5, 1.5)) >>> v = 1 / numerix.sqrt(2) >>> answer = CellVariable(mesh=mesh, ... value=(((0, 0, v, 0), ... (0, 0, 0, 0), ... (0, 0, 0, 0), ... (0, v, 0, 0)), ... ((0, 0, v, 0), ... (0, 0, 0, 0), ... (0, 0, 0, 0), ... (0, v, 0, 0)))) >>> print numerix.allclose(distanceVariable._cellInterfaceNormals, answer) True """ dim = self.mesh.dim valueOverFaces = numerix.repeat(self._cellValueOverFaces[numerix.newaxis, ...], dim, axis=0) cellFaceIDs = self.mesh.cellFaceIDs if cellFaceIDs.shape[-1] > 0: interfaceNormals = self._interfaceNormals[...,cellFaceIDs] else: interfaceNormals = 0 return MA.where(valueOverFaces < 0, 0, interfaceNormals)
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
def _interfaceNormals(self): """ Returns the normals on the boundary faces only, the other are set to zero. >>> from fipy.meshes import Grid2D >>> from fipy.variables.faceVariable import FaceVariable >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2) >>> distanceVariable = DistanceVariable(mesh = mesh, ... value = (-0.5, 0.5, 0.5, 1.5)) >>> v = 1 / numerix.sqrt(2) >>> answer = FaceVariable(mesh=mesh, ... value=((0, 0, v, 0, 0, 0, 0, v, 0, 0, 0, 0), ... (0, 0, v, 0, 0, 0, 0, v, 0, 0, 0, 0))) >>> print numerix.allclose(distanceVariable._interfaceNormals, answer) True """ M = self.mesh.dim interfaceFlag = numerix.repeat(self._interfaceFlag[numerix.newaxis, ...], M, axis=0) return numerix.where(interfaceFlag, self._levelSetNormals, 0)
def _cellToCellIDsFilled(self): N = self.numberOfCells M = self._maxFacesPerCell cellIDs = numerix.repeat(numerix.arange(N)[numerix.newaxis, ...], M, axis=0) cellToCellIDs = self._cellToCellIDs return MA.where(MA.getmaskarray(cellToCellIDs), cellIDs, cellToCellIDs)
def _calcFaceAreas(self): faceVertexIDs = MA.filled(self.faceVertexIDs, -1) substitute = numerix.repeat(faceVertexIDs[numerix.newaxis, 0], faceVertexIDs.shape[0], axis=0) faceVertexIDs = numerix.where(MA.getmaskarray(self.faceVertexIDs), substitute, faceVertexIDs) faceVertexCoords = numerix.take(self.vertexCoords, faceVertexIDs, axis=1) faceOrigins = numerix.repeat(faceVertexCoords[:,0], faceVertexIDs.shape[0], axis=0) faceOrigins = numerix.reshape(faceOrigins, MA.shape(faceVertexCoords)) faceVertexCoords = faceVertexCoords - faceOrigins left = range(faceVertexIDs.shape[0]) right = left[1:] + [left[0]] cross = numerix.sum(numerix.cross(faceVertexCoords, numerix.take(faceVertexCoords, right, 1), axis=0), 1) return numerix.sqrtDot(cross, cross) / 2.
def _createVertices(self): x = self._calcVertexCoordinates(self.dx, self.nx) x = numerix.resize(x, (self.numberOfVertices,)) y = self._calcVertexCoordinates(self.dy, self.ny) y = numerix.repeat(y, self.numberOfVerticalColumns) return numerix.array((x, y))
def createVertices(nx, ny, dx, dy, numVerts, numVertCols): x = _AbstractGridBuilder.calcVertexCoordinates(dx, nx) x = numerix.resize(x, (numVerts,)) y = _AbstractGridBuilder.calcVertexCoordinates(dy, ny) y = numerix.repeat(y, numVertCols) return numerix.array((x, y))
def createVertices(nx, ny, dx, dy, numVerts, numVertCols): x = _AbstractGridBuilder.calcVertexCoordinates(dx, nx) x = numerix.resize(x, (numVerts, )) y = _AbstractGridBuilder.calcVertexCoordinates(dy, ny) y = numerix.repeat(y, numVertCols) return numerix.array((x, y))
def setValue(self, value, unit = None, where = None): if where is not None: shape = numerix.getShape(where) if shape != self.shape \ and shape == self._getShapeFromMesh(mesh=self.getMesh()): for dim in self.elementshape: where = numerix.repeat(where[numerix.newaxis, ...], repeats=dim, axis=0) return Variable.setValue(self, value=value, unit=unit, where=where)
def setValue(self, value, unit=None, where=None): if where is not None: shape = numerix.getShape(where) if shape != self.shape \ and shape == self._getShapeFromMesh(mesh=self.mesh): for dim in self.elementshape: where = numerix.repeat(where[numerix.newaxis, ...], repeats=dim, axis=0) return Variable.setValue(self, value=value, unit=unit, where=where)
def _calcCellNormals(self): cellNormals = numerix.take(self._getFaceNormals(), self._getCellFaceIDs(), axis=1) cellFaceCellIDs = numerix.take(self.faceCellIDs[0], self.cellFaceIDs) cellIDs = numerix.repeat(numerix.arange(self.getNumberOfCells())[numerix.newaxis,...], self._getMaxFacesPerCell(), axis=0) direction = (cellFaceCellIDs == cellIDs) * 2 - 1 if self._getMaxFacesPerCell() > 0: self.cellNormals = direction[numerix.newaxis, ...] * cellNormals else: self.cellNormals = cellNormals
def _calcCellNormals(self): cellNormals = numerix.take(self.faceNormals, self.cellFaceIDs, axis=1) cellFaceCellIDs = numerix.take(self.faceCellIDs[0], self.cellFaceIDs) cellIDs = numerix.repeat(numerix.arange(self.numberOfCells)[numerix.newaxis,...], self._maxFacesPerCell, axis=0) direction = (cellFaceCellIDs == cellIDs) * 2 - 1 if self._maxFacesPerCell > 0: return direction[numerix.newaxis, ...] * cellNormals else: return cellNormals
def _iadd(self, other, sign=1): if hasattr(other, "matrix"): self.matrix = self.matrix + (sign * other.matrix) elif type(other) in [float, int]: fillVec = numerix.repeat(other, self.matrix.nnz) self.matrix = self.matrix \ + sp.csr_matrix((fillVec, self.matrix.nonzero()), self.matrix.shape) else: self.matrix = self.matrix + (sign * other) return self
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))
def putDiagonal(self, vector): """ Put elements of `vector` along diagonal of matrix >>> L = _ScipyMatrixFromShape(size=3) >>> L.putDiagonal([3., 10., numerix.pi]) >>> print(L) 3.000000 --- --- --- 10.000000 --- --- --- 3.141593 >>> L.putDiagonal([10., 3.]) >>> print(L) 10.000000 --- --- --- 3.000000 --- --- --- 3.141593 """ if type(vector) in [int, float]: vector = numerix.repeat(vector, self._shape[0]) self.matrix.setdiag(vector)
def putDiagonal(self, vector): """ Put elements of `vector` along diagonal of matrix >>> L = _ScipyMatrixFromShape(size=3) >>> L.putDiagonal([3.,10.,numerix.pi]) >>> print L 3.000000 --- --- --- 10.000000 --- --- --- 3.141593 >>> L.putDiagonal([10.,3.]) >>> print L 10.000000 --- --- --- 3.000000 --- --- --- 3.141593 """ if type(vector) in [int, float]: vector = numerix.repeat(vector, self._shape[0]) self.matrix.setdiag(vector)
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.
def _cellValueOverFaces(self): """ Returns the cells values at the faces. >>> from fipy.meshes import Grid2D >>> from fipy.variables.cellVariable import CellVariable >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2) >>> distanceVariable = DistanceVariable(mesh = mesh, ... value = (-0.5, 0.5, 0.5, 1.5)) >>> answer = CellVariable(mesh=mesh, ... value=((-.5, .5, .5, 1.5), ... (-.5, .5, .5, 1.5), ... (-.5, .5, .5, 1.5), ... (-.5, .5, .5, 1.5))) >>> print numerix.allclose(distanceVariable._cellValueOverFaces, answer) True """ M = self.mesh._maxFacesPerCell N = self.mesh.numberOfCells return numerix.reshape(numerix.repeat(numerix.array(self._value)[numerix.newaxis, ...], M, axis=0), (M, N))
def _getCellInterfaceNormals(self): """ Returns the interface normals over the cells. >>> from fipy.meshes.grid2D import Grid2D >>> from fipy.variables.cellVariable import CellVariable >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2) >>> distanceVariable = DistanceVariable(mesh = mesh, ... value = (-0.5, 0.5, 0.5, 1.5)) >>> v = 1 / numerix.sqrt(2) >>> answer = CellVariable(mesh=mesh, ... value=(((0, 0, v, 0), ... (0, 0, 0, 0), ... (0, 0, 0, 0), ... (0, v, 0, 0)), ... ((0, 0, v, 0), ... (0, 0, 0, 0), ... (0, 0, 0, 0), ... (0, v, 0, 0)))) >>> print numerix.allclose(distanceVariable._getCellInterfaceNormals(), answer) True """ N = self.mesh.getNumberOfCells() M = self.mesh._getMaxFacesPerCell() dim = self.mesh.getDim() valueOverFaces = numerix.repeat(self._getCellValueOverFaces()[numerix.newaxis, ...], dim, axis=0) if self.cellFaceIDs.shape[-1] > 0: interfaceNormals = self._getInterfaceNormals()[...,self.cellFaceIDs] else: interfaceNormals = 0 from fipy.tools.numerix import MA return MA.where(valueOverFaces < 0, 0, interfaceNormals)
def addAtDiagonal(self, vector): if type(vector) in [type(1), type(1.)]: vector = numerix.repeat(vector, self._shape[0]) ids = numerix.arange(len(vector)) self.addAt(vector, ids, ids)
def _faceAreas(self): return numerix.concatenate((numerix.repeat((self.dx * self.dy,), self.numberOfXYFaces), numerix.repeat((self.dx * self.dz,), self.numberOfXZFaces), numerix.repeat((self.dy * self.dz,), self.numberOfYZFaces)))
def addAtDiagonal(self, vector): if isinstance(vector, (int, float)): vector = numerix.repeat(vector, self._shape[0]) ids = numerix.arange(len(vector)) self.addAt(vector, ids, ids)
def _calcCellToCellIDsFilled(self): N = self.getNumberOfCells() M = self._getMaxFacesPerCell() cellIDs = numerix.repeat(numerix.arange(N)[numerix.newaxis, ...], M, axis=0) cellToCellIDs = self._getCellToCellIDs() self.cellToCellIDsFilled = MA.where(MA.getmaskarray(cellToCellIDs), cellIDs, cellToCellIDs)