def _buildMatrixPy(self, L, oldArray, b, dt, coeffVectors): N = len(oldArray) b += numerix.array(oldArray) * numerix.array(coeffVectors['old value']) / dt b += numerix.ones([N]) * numerix.array(coeffVectors['b vector']) L.addAtDiagonal(numerix.ones([N]) * numerix.array(coeffVectors['new value']) / dt) L.addAtDiagonal(numerix.ones([N]) * numerix.array(coeffVectors['diagonal']))
def _cellAreas(self): areas = numerix.ones((4, self.numberOfCells), 'd') areas[0] = self.dx areas[1] = self.dy areas[2] = self.dx areas[3] = self.dy return areas
def _getNumberOfFacesPerCell(self): cellFaceIDs = self._getCellFaceIDs() if type(cellFaceIDs) is type(MA.array(0)): ## bug in count returns float values when there is no mask return numerix.array(cellFaceIDs.count(axis=0), 'l') else: return self._getMaxFacesPerCell() * numerix.ones(cellFaceIDs.shape[-1], 'l')
def _getFaceNormals(self): faceNormals = numerix.ones((1, self.numberOfFaces), "d") # The left-most face has neighboring cells None and the left-most cell. # We must reverse the normal to make fluxes work correctly. if self.numberOfFaces > 0: faceNormals[..., 0] *= -1 return faceNormals
def _getCellDistances(self): distances = numerix.ones(self.numberOfFaces, "d") distances *= self.dx if len(distances) > 0: distances[0] = self.dx / 2.0 distances[-1] = self.dx / 2.0 return distances
def _cellAreas(self): areas = numerix.ones((4, self.numberOfCells), 'd') areas[0] = self.dx * self._cellCenters[0] areas[1] = self.dy * (self._cellCenters[0] + self.dx / 2) areas[2] = self.dx * self._cellCenters[0] areas[3] = self.dy * (self._cellCenters[0] - self.dx / 2) return areas
def __rmul__(self, other): if type(numerix.ones(1)) == type(other): y = other.copy() self.matrix.matvec_transp(other, y) return y else: return self * other
def __rmul__(self, other): if isinstance(numerix.ones(1, 'l'), type(other)): y = other.copy() self.matrix.matvec_transp(other, y) return y else: return self * other
def _calcFaceNormals(self): faceNormals = numerix.array((numerix.ones(self.numberOfFaces, 'd'), )) # The left-most face has neighboring cells None and the left-most cell. # We must reverse the normal to make fluxes work correctly. if self.numberOfFaces > 0: faceNormals[..., 0] = -faceNormals[..., 0] return faceNormals
def _numberOfFacesPerCell(self): cellFaceIDs = self.cellFaceIDs if isinstance(cellFaceIDs, type(MA.array(0))): ## bug in count returns float values when there is no mask return numerix.array(cellFaceIDs.count(axis=0), 'l') else: return self._maxFacesPerCell * numerix.ones(cellFaceIDs.shape[-1], 'l')
def quiver(self, sparsity=None, scale=None): var = self.vars[0] mesh = var.mesh if isinstance(var, FaceVariable): N = mesh.numberOfFaces X, Y = mesh.faceCenters elif isinstance(var, CellVariable): N = mesh.numberOfCells X, Y = mesh.cellCenters if sparsity is not None and N > sparsity: XYrand = numerix.random.random((2, sparsity)) XYrand = numerix.array([[min(X)], [min(Y)]]) + XYrand * numerix.array([[max(X) - min(X)], [max(Y) - min(Y)]]) self.indices = numerix.nearest(numerix.array([X, Y]), XYrand) else: self.indices = numerix.arange(N) X = numerix.take(X, self.indices) Y = numerix.take(Y, self.indices) U = V = numerix.ones(X.shape, 'l') if hasattr(self, "_quiver"): self._quiver.remove() self._quiver = self.axes.quiver(X, Y, U, V, scale=scale, pivot='middle')
def quiver(self, sparsity=None, scale=None): var = self.vars[0] mesh = var.mesh if isinstance(var, FaceVariable): N = mesh.numberOfFaces X, Y = mesh.faceCenters elif isinstance(var, CellVariable): N = mesh.numberOfCells X, Y = mesh.cellCenters if sparsity is not None and N > sparsity: XYrand = numerix.random.random((2, sparsity)) XYrand = numerix.array([ [min(X)], [min(Y)] ]) + XYrand * numerix.array([[max(X) - min(X)], [max(Y) - min(Y)]]) self.indices = numerix.nearest(numerix.array([X, Y]), XYrand) else: self.indices = numerix.arange(N) X = numerix.take(X, self.indices) Y = numerix.take(Y, self.indices) U = V = numerix.ones(X.shape, 'l') if hasattr(self, "_quiver"): self._quiver.remove() self._quiver = self.axes.quiver(X, Y, U, V, scale=scale, pivot='middle')
def _cellDistances(self): distances = numerix.ones(self.numberOfFaces, 'd') distances *= self.dx if len(distances) > 0: distances[0] = self.dx / 2. distances[-1] = self.dx / 2. return distances
def _calcValue(self): ids = self.mesh.cellFaceIDs contributions = numerix.take(self.faceVariable, ids, axis=-1) s = (numerix.newaxis, ) * (len(contributions.shape) - 2) + (slice( 0, None, None), ) + (slice(0, None, None), ) faceContributions = contributions * self.mesh._cellToFaceOrientations[ s] #just changes sign temp = faceContributions.copy() maskedValues = np.vstack( ([not isinstance(xi, float) for xi in temp[0] ], [not isinstance(xi, float) for xi in temp[1] ], [not isinstance(xi, float) for xi in temp[2]], [not isinstance(xi, float) for xi in temp[3]])) faceAreas = np.take(self.mesh._faceAreas, ids) faceAreas = MA.masked_where(maskedValues, faceAreas) if (len(temp) > 1): temp = temp * faceAreas temp[2] = numerix.MA.filled(temp[2], temp[0]) temp[3] = numerix.MA.filled(temp[3], temp[1]) faceAreas[2] = numerix.MA.filled(faceAreas[2], faceAreas[0]) faceAreas[3] = numerix.MA.filled(faceAreas[3], faceAreas[1]) faceAreas[0] = (faceAreas[0] + faceAreas[2]) faceAreas[1] = (faceAreas[1] + faceAreas[3]) temp[0] = (temp[0] + temp[2]) / faceAreas[0] temp[1] = (temp[1] + temp[3]) / faceAreas[1] temp = numerix.vstack( (numerix.array(temp[0]), numerix.array(temp[1]))) return numerix.tensordot(numerix.ones(temp.shape[-2], 'd'), temp, (0, -2)) / self.mesh.cellVolumes
def _getFaceToCellDistanceRatio(self): distances = numerix.ones(self.numberOfFaces, "d") distances *= 0.5 if len(distances) > 0: distances[0] = 1 distances[-1] = 1 return distances
def _cellToFaceOrientations(self): cellFaceOrientations = numerix.ones((4, self.numberOfCells), 'l') if self.numberOfCells > 0: cellFaceOrientations[0, self.nx:] = -1 cellFaceOrientations[3, :] = -1 cellFaceOrientations[3, ::self.nx] = 1 return cellFaceOrientations
def _cellToFaceOrientations(self): cellFaceOrientations = numerix.ones((4, self.numberOfCells), 'l') if self.numberOfCells > 0: cellFaceOrientations[0, self.nx:] = -1 cellFaceOrientations[3,:] = -1 cellFaceOrientations[3, ::self.nx] = 1 return cellFaceOrientations
def quiver(self, sparsity=None, scale=None): var = self.vars[0] mesh = var.getMesh() if isinstance(var, FaceVariable): N = mesh._getNumberOfFaces() V = mesh._getFaceAreas() X, Y = mesh.getFaceCenters() elif isinstance(var, CellVariable): N = mesh.getNumberOfCells() V = mesh.getCellVolumes() X, Y = mesh.getCellCenters() if sparsity is not None and N > sparsity: self.indices = numerix.random.rand(N) * V self.indices = self.indices.argsort()[-sparsity:] else: self.indices = numerix.arange(N) X = numerix.take(X, self.indices) Y = numerix.take(Y, self.indices) U = V = numerix.ones(X.shape) import pylab pylab.ion() pylab.cla() self._quiver = pylab.quiver(X, Y, U, V, scale=scale) pylab.ioff()
def _calcFaceNormals(self): faceNormals = numerix.array((numerix.ones(self.numberOfFaces, 'd'),)) # The left-most face has neighboring cells None and the left-most cell. # We must reverse the normal to make fluxes work correctly. if self.numberOfFaces > 0: faceNormals[...,0] = -faceNormals[...,0] return faceNormals
def faceNormals(self): faceNormals = numerix.ones((1, self.numberOfFaces), 'd') # The left-most face has neighboring cells None and the left-most cell. # We must reverse the normal to make fluxes work correctly. if self.numberOfFaces > 0: faceNormals[..., 0] *= -1 return faceNormals
def __rmul__(self, other): if type(numerix.ones(1)) == type(other): y = Epetra.Vector(other) result = Epetra.Vector(self.nonOverlappingMap) self._getMatrix().Multiply(True, y, result) return _trilinosToNumpyVector(result) else: return self * other
def _cellAreas(self): areas = numerix.ones((6, self.numberOfCells), 'd') areas[0] = self.dy * self.dz areas[1] = self.dy * self.dz areas[2] = self.dx * self.dz areas[3] = self.dx * self.dz areas[4] = self.dx * self.dy areas[5] = self.dx * self.dy return areas
def __rmul__(self, other): if isinstance(numerix.ones(1, 'l'), type(other)): self.fillComplete() y = Epetra.Vector(self.rangeMap, other) result = Epetra.Vector(self.domainMap) self.matrix.Multiply(True, y, result) return numerix.array(result) else: return self * other
def __rmul__(self, other): if type(numerix.ones(1, 'l')) == type(other): N = self._shape[1] x = PETSc.Vec().createMPI(N, comm=self.matrix.comm) y = x.duplicate() x[:] = other self.matrix.multTranspose(x, y) return numerix.asarray(y) else: return self * other
def __init__(self, size): """Create a sparse matrix with '1' in the diagonal >>> print(_PysparseIdentityMatrix(size=3)) 1.000000 --- --- --- 1.000000 --- --- --- 1.000000 """ _PysparseMatrixFromShape.__init__(self, rows=size, cols=size, bandwidth = 1) ids = numerix.arange(size) self.put(numerix.ones(size, 'd'), ids, ids)
def __init__(self, size): """Create a sparse matrix with `1` in the diagonal >>> print(_PysparseIdentityMatrix(size=3)) 1.000000 --- --- --- 1.000000 --- --- --- 1.000000 """ _PysparseMatrixFromShape.__init__(self, rows=size, cols=size, bandwidth=1) ids = numerix.arange(size) self.put(numerix.ones(size, 'd'), ids, ids)
def __init__(self, size): """ Create a sparse matrix with '1' in the diagonal >>> print _TrilinosIdentityMatrix(size=3) 1.000000 --- --- --- 1.000000 --- --- --- 1.000000 """ _TrilinosMatrix.__init__(self, size=size, bandwidth=1) ids = numerix.arange(size) self.addAt(numerix.ones(size), ids, ids)
def __init__(self, size): """ Create a sparse matrix with '1' in the diagonal >>> print _ScipyIdentityMatrix(size=3) 1.000000 --- --- --- 1.000000 --- --- --- 1.000000 """ _ScipyMatrixFromShape.__init__(self, size=size, bandwidth=1) ids = numerix.arange(size) self.put(numerix.ones(size, 'd'), ids, ids)
def __init__(self, size): """ Create a sparse matrix with '1' in the diagonal >>> print _PysparseIdentityMatrix(size=3) 1.000000 --- --- --- 1.000000 --- --- --- 1.000000 """ _PysparseMatrix.__init__(self, size=size, bandwidth=1) ids = numerix.arange(size) self.put(numerix.ones(size, "d"), ids, ids)
def _faceToCellDistanceRatio(self): """how far face is from first to second cell distance from center of face to center of first cell divided by distance between cell centers """ distances = numerix.ones(self.numberOfFaces, 'd') distances *= 0.5 if len(distances) > 0: distances[0] = 1 distances[-1] = 1 return distances
def _calcValueNoInline(self): ids = self.mesh.cellFaceIDs contributions = numerix.take(self.faceVariable, ids, axis=-1) # FIXME: numerix.MA.filled casts away dimensions s = (numerix.newaxis,) * (len(contributions.shape) - 2) + (slice(0,None,None),) + (slice(0,None,None),) faceContributions = contributions * self.mesh._cellToFaceOrientations[s] return numerix.tensordot(numerix.ones(faceContributions.shape[-2], 'd'), numerix.MA.filled(faceContributions, 0.), (0, -2)) / self.mesh.cellVolumes
def _calcInteriorAndExteriorCellIDs(self): try: import sets self.exteriorCellIDs = sets.Set(self.faceCellIDs[0, self.getExteriorFaces().getValue()]) self.interiorCellIDs = list(sets.Set(range(self.numberOfCells)) - self.exteriorCellIDs) self.exteriorCellIDs = list(self.exteriorCellIDs) except: self.exteriorCellIDs = self.faceCellIDs[0, self.getExteriorFaces().getValue()] tmp = numerix.zeros(self.numberOfCells) numerix.put(tmp, self.exteriorCellIDs, numerix.ones(len(self.exteriorCellIDs))) self.exteriorCellIDs = numerix.nonzero(tmp) self.interiorCellIDs = numerix.nonzero(numerix.logical_not(tmp))
def __init__(self, mesh): """ Create a sparse matrix associated with a `Mesh` with `1` in the diagonal >>> from fipy import Grid1D >>> mesh = Grid1D(nx=3) >>> print(_TrilinosIdentityMeshMatrix(mesh=mesh)) 1.000000 --- --- --- 1.000000 --- --- --- 1.000000 """ _TrilinosMeshMatrix.__init__(self, mesh=mesh, bandwidth=1) size = mesh.numberOfCells ids = numerix.arange(size) self.addAt(numerix.ones(size, 'l'), ids, ids)
def _calcValueNoInline(self): ids = self.mesh.cellFaceIDs contributions = numerix.take(self.faceVariable, ids, axis=-1) # FIXME: numerix.MA.filled casts away dimensions s = (numerix.newaxis, ) * (len(contributions.shape) - 2) + (slice( 0, None, None), ) + (slice(0, None, None), ) faceContributions = contributions * self.mesh._cellToFaceOrientations[s] return numerix.tensordot( numerix.ones(faceContributions.shape[-2], 'd'), numerix.MA.filled(faceContributions, 0.), (0, -2)) / self.mesh.cellVolumes
def _calcInteriorAndExteriorCellIDs(self): try: import sys if sys.version_info < (2, 6): from sets import Set as set exteriorCellIDs = set(self.faceCellIDs[0, self._exteriorFaces.value]) interiorCellIDs = list(set(range(self.numberOfCells)) - self._exteriorCellIDs) exteriorCellIDs = list(self._exteriorCellIDs) except: exteriorCellIDs = self.faceCellIDs[0, self._exteriorFaces.value] tmp = numerix.zeros(self.numberOfCells, 'l') numerix.put(tmp, exteriorCellIDs, numerix.ones(len(exteriorCellIDs), 'l')) exteriorCellIDs = numerix.nonzero(tmp) interiorCellIDs = numerix.nonzero(numerix.logical_not(tmp)) return interiorCellIDs, exteriorCellIDs
def __init__(self, mesh): """ Create a sparse matrix associated with a `Mesh` with '1' in the diagonal >>> from fipy import Grid1D >>> mesh = Grid1D(nx=3) >>> print _TrilinosIdentityMeshMatrix(mesh=mesh) 1.000000 --- --- --- 1.000000 --- --- --- 1.000000 """ _TrilinosMeshMatrix.__init__(self, mesh=mesh, bandwidth=1) size = mesh.getNumberOfCells() ids = numerix.arange(size) self.addAt(numerix.ones(size), ids, ids)
def __mul__(self, other): """ Multiply a sparse matrix by another sparse matrix >>> L1 = _PysparseMatrixFromShape(rows=3, cols=3) >>> L1.put([3.,10.,numerix.pi,2.5], [0,0,1,2], [2,1,1,0]) >>> L2 = _PysparseIdentityMatrix(size=3) >>> L2.put([4.38,12357.2,1.1], [2,1,0], [1,0,2]) >>> tmp = numerix.array(((1.23572000e+05, 2.31400000e+01, 3.00000000e+00), ... (3.88212887e+04, 3.14159265e+00, 0.00000000e+00), ... (2.50000000e+00, 0.00000000e+00, 2.75000000e+00))) >>> numerix.allclose((L1 * L2).numpyArray, tmp) 1 or a sparse matrix by a vector >>> tmp = numerix.array((29., 6.28318531, 2.5)) >>> numerix.allclose(L1 * numerix.array((1,2,3),'d'), tmp) 1 or a vector by a sparse matrix >>> tmp = numerix.array((7.5, 16.28318531, 3.)) >>> numerix.allclose(numerix.array((1,2,3),'d') * L1, tmp) ## The multiplication is broken. Numpy is calling __rmul__ for every element instead of with the whole array. 1 """ N = self.matrix.shape[1] if isinstance(other, _PysparseMatrix): return _PysparseMatrix( matrix=spmatrix.matrixmultiply(self.matrix, other.matrix)) else: shape = numerix.shape(other) if shape == (): L = spmatrix.ll_mat(N, N, N) L.put(other * numerix.ones(N, 'l')) return _PysparseMatrix( matrix=spmatrix.matrixmultiply(self.matrix, L)) elif shape == (N, ): y = numerix.empty((self.matrix.shape[0], )) self.matrix.matvec(other, y) return y else: raise TypeError
def _getStencil_(self, id1, id2, globalOverlappihgIDs, globalNonOverlappihgIDs, overlapping=False): id1 = globalOverlappihgIDs[id1] if overlapping: mask = numerix.ones(id1.shape, dtype=bool) else: mask = numerix.in1d(id1, globalNonOverlappihgIDs) id1 = self.matrix()._mesh2matrix(id1[mask]) id2 = numerix.asarray(id2)[mask] return id1, id2, mask
def __mul__(self, other): """ Multiply a sparse matrix by another sparse matrix >>> L1 = _PysparseMatrix(size = 3) >>> L1.put([3.,10.,numerix.pi,2.5], [0,0,1,2], [2,1,1,0]) >>> L2 = _PysparseIdentityMatrix(size = 3) >>> L2.put([4.38,12357.2,1.1], [2,1,0], [1,0,2]) >>> tmp = numerix.array(((1.23572000e+05, 2.31400000e+01, 3.00000000e+00), ... (3.88212887e+04, 3.14159265e+00, 0.00000000e+00), ... (2.50000000e+00, 0.00000000e+00, 2.75000000e+00))) >>> numerix.allclose((L1 * L2).getNumpyArray(), tmp) 1 or a sparse matrix by a vector >>> tmp = numerix.array((29., 6.28318531, 2.5)) >>> numerix.allclose(L1 * numerix.array((1,2,3),'d'), tmp) 1 or a vector by a sparse matrix >>> tmp = numerix.array((7.5, 16.28318531, 3.)) >>> numerix.allclose(numerix.array((1,2,3),'d') * L1, tmp) ## The multiplication is broken. Numpy is calling __rmul__ for every element instead of with the whole array. 1 """ N = self.matrix.shape[0] if isinstance(other, _PysparseMatrix): return _PysparseMatrix(matrix = spmatrix.matrixmultiply(self.matrix, other._getMatrix())) else: shape = numerix.shape(other) if shape == (): L = spmatrix.ll_mat(N, N, N) L.put(other * numerix.ones(N)) return _PysparseMatrix(matrix = spmatrix.matrixmultiply(self.matrix, L)) elif shape == (N,): y = other.copy() self.matrix.matvec(other, y) return y else: raise TypeError
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
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) }
def _calcFaceAreas(self): return numerix.ones(self.numberOfFaces, 'd')
def _cellToFaceOrientations(self): orientations = numerix.ones((2, self.numberOfCells), 'l') if self.numberOfCells > 0: orientations[0] *= -1 orientations[0, 0] = 1 return orientations
def _cellVolumes(self): return numerix.ones(self.numberOfCells, 'd') * self.dx * self.dy
def _extrude(self, mesh, extrudeFunc, layers): ## should extrude self rather than creating a new mesh? ## the following allows the 2D mesh to be in 3D space, this can be the case for a ## Gmsh2DIn3DSpace which would then be extruded. oldVertices = mesh.vertexCoords if oldVertices.shape[0] == 2: oldVertices = numerix.resize(oldVertices, (3, len(oldVertices[0]))) oldVertices[2] = 0 NCells = mesh.numberOfCells NFac = mesh.numberOfFaces NFacPerCell = mesh._maxFacesPerCell ## set up the initial data arrays new_shape = (max(NFacPerCell, 4), (1 + layers)*NCells + layers*NFac) faces = numerix.MA.masked_values(-numerix.ones(new_shape, 'l'), value = -1) orderedVertices = mesh._orderedCellVertexIDs faces[:NFacPerCell, :NCells] = orderedVertices vertices = oldVertices vert0 = mesh.faceVertexIDs faceCount = NCells for layer in range(layers): ## need this later initialFaceCount = faceCount ## build the vertices newVertices = extrudeFunc(oldVertices) vertices = numerix.concatenate((vertices, newVertices), axis=1) ## build the faces along the layers faces[:NFacPerCell, faceCount: faceCount + NCells] = orderedVertices + len(oldVertices[0]) * (layer + 1) try: # numpy 1.1 doesn't copy right side before assigning slice # See: http://www.mail-archive.com/[email protected]/msg09843.html faces[:NFacPerCell, faceCount: faceCount + NCells] = faces[:NFacPerCell, faceCount: faceCount + NCells][::-1,:].copy() except: faces[:NFacPerCell, faceCount: faceCount + NCells] = faces[:NFacPerCell, faceCount: faceCount + NCells][::-1,:] faceCount = faceCount + NCells vert1 = (vert0 + len(oldVertices[0]))[::-1,:] ## build the faces between the layers faces[:4, faceCount: faceCount + NFac] = numerix.concatenate((vert0, vert1), axis = 0)[::-1,:] vert0 = vert0 + len(oldVertices[0]) NCells = mesh.numberOfCells ## build the cells, the first layer has slightly different ordering if layer == 0: c0 = numerix.reshape(numerix.arange(NCells), (1, NCells)) cells = numerix.concatenate((c0, c0 + NCells, mesh.cellFaceIDs + 2 * NCells), axis = 0) else: newCells = numerix.concatenate((c0, c0 + initialFaceCount, mesh.cellFaceIDs + faceCount), axis=0) newCells[0] = cells[1, -NCells:] cells = numerix.concatenate((cells, newCells), axis=1) ## keep a count of things for the next layer faceCount = faceCount + NFac oldVertices = newVertices ## return a new mesh, extrude could just as easily act on self return Mesh(vertices, faces, cells, communicator=mesh.communicator)
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) }
def __rmul__(self, other): if isinstance(numerix.ones(1, 'l'), type(other)): y = self.matrix.transpose() * other.copy() return y else: return self * other
index_phi] # pulling out the values of the rho corresponding to index_phi yvar = rho_at_index[ 0, :] # storing the values of rho corresponding to index_phi into xvar rho_sorted_acc_to_theta = index_sorted( xvar, yvar) # calling the index_sorted function rho_sorted_acc_to_theta = np.reshape( rho_sorted_acc_to_theta, (1, len(rho_sorted_acc_to_theta))) # reshaping into a single array theta_sorted = np.sort(theta_at_index) # theta value sorted theta_sorted = theta_sorted[ 0, :] # converting from 1Xn matrix to row array of n elements phi_new = phi_value * numerix.ones(len(theta_sorted)) m_cell_modified_sph_pol = numerix.append( numerix.asarray(r_at_index), [numerix.asarray(theta_sorted), numerix.asarray(phi_new)], axis=0) #print(numerix.shape(m_cell_modified_sph_pol)) m_cell_sph = numerix.append( m_cell_sph, (m_cell_modified_sph_pol), axis=1) #Appending the m values in spherical polar coordinate theta_sz = np.shape(theta_sorted) size = theta_sz[0] total_size = total_size + size # calculate total number of cells being covered during calculation
def _cellVolumes(self): return numerix.ones(self.numberOfCells, 'd') * self.dx * self.dy * self.dz
def _extrude(self, mesh, extrudeFunc, layers): ## should extrude cnahe self rather than creating a new mesh? ## the following allows the 2D mesh to be in 3D space, this can be the case for a ## Gmsh2DIn3DSpace which would then be extruded. oldVertices = mesh.vertexCoords if oldVertices.shape[0] == 2: oldVertices = numerix.resize(oldVertices, (3, len(oldVertices[0]))) oldVertices[2] = 0 NCells = mesh.numberOfCells NFac = mesh.numberOfFaces NFacPerCell = mesh._maxFacesPerCell ## set up the initial data arrays new_shape = (max(NFacPerCell, 4), (1 + layers)*NCells + layers*NFac) faces = numerix.MA.masked_values(-numerix.ones(new_shape, 'l'), value = -1) orderedVertices = mesh._orderedCellVertexIDs faces[:NFacPerCell, :NCells] = orderedVertices vertices = oldVertices vert0 = mesh.faceVertexIDs faceCount = NCells for layer in range(layers): ## need this later initialFaceCount = faceCount ## build the vertices newVertices = extrudeFunc(oldVertices) vertices = numerix.concatenate((vertices, newVertices), axis=1) ## build the faces along the layers faces[:NFacPerCell, faceCount: faceCount + NCells] = orderedVertices + len(oldVertices[0]) * (layer + 1) try: # numpy 1.1 doesn't copy right side before assigning slice # See: http://www.mail-archive.com/[email protected]/msg09843.html faces[:NFacPerCell, faceCount: faceCount + NCells] = faces[:NFacPerCell, faceCount: faceCount + NCells][::-1,:].copy() except: faces[:NFacPerCell, faceCount: faceCount + NCells] = faces[:NFacPerCell, faceCount: faceCount + NCells][::-1,:] faceCount = faceCount + NCells vert1 = (vert0 + len(oldVertices[0]))[::-1,:] ## build the faces between the layers faces[:4, faceCount: faceCount + NFac] = numerix.concatenate((vert0, vert1), axis = 0)[::-1,:] vert0 = vert0 + len(oldVertices[0]) NCells = mesh.numberOfCells ## build the cells, the first layer has slightly different ordering if layer == 0: c0 = numerix.reshape(numerix.arange(NCells), (1, NCells)) cells = numerix.concatenate((c0, c0 + NCells, mesh.cellFaceIDs + 2 * NCells), axis = 0) else: newCells = numerix.concatenate((c0, c0 + initialFaceCount, mesh.cellFaceIDs + faceCount), axis=0) newCells[0] = cells[1,-NCells:] cells = numerix.concatenate((cells, newCells), axis=1) ## keep a count of things for the next layer faceCount = faceCount + NFac oldVertices = newVertices ## return a new mesh, extrude could just as easily act on self return Mesh(vertices, faces, cells, communicator=mesh.communicator)