def func(v): dMdm = spzeros(n_items, inv_items) if tensor_type == 0: for P in Ps: dMdm = dMdm + sp.csr_matrix( (P.T * (P * v), (range(n_items), np.zeros(n_items))), shape=(n_items, inv_items)) elif tensor_type == 1: for P in Ps: ys = P @ v dMdm = dMdm + P.T @ sp.csr_matrix( (ys, col_inds, ind_ptr), shape=(n_cells * dim, inv_items)) elif tensor_type == 2: for P in Ps: ys = P @ v dMdm = dMdm + P.T @ sp.csr_matrix( (ys, col_inds, ind_ptr), shape=(n_cells * dim, inv_items)) elif tensor_type == 3: for P in Ps: ys = P @ v ys = np.repeat(ys, dim).reshape((-1, dim, dim)) ys = ys.transpose((0, 2, 1)).reshape(-1) dMdm = dMdm + P.T @ sp.csr_matrix( (ys, col_inds, ind_ptr), shape=(n_cells * dim, inv_items)) return dMdm
def _edgeCurlStencily(self): n = self.vnC # The number of cell centers in each direction D31 = kron3(ddx(n[2]), speye(n[1] + 1), speye(n[0])) D13 = kron3(speye(n[2]), speye(n[1] + 1), ddx(n[0])) # O2 = spzeros(np.shape(D31)[0], np.shape(D32)[1]) O2 = spzeros(n[0] * (n[1] + 1) * n[2], (n[0] + 1) * n[1] * (n[2] + 1)) return sp.hstack((D31, O2, -D13))
def _edgeCurlStencilz(self): n = self.vnC # The number of cell centers in each direction D21 = kron3(speye(n[2] + 1), ddx(n[1]), speye(n[0])) D12 = kron3(speye(n[2] + 1), speye(n[1]), ddx(n[0])) # O3 = spzeros(np.shape(D21)[0], np.shape(D13)[1]) O3 = spzeros(n[0] * n[1] * (n[2] + 1), (n[0] + 1) * (n[1] + 1) * n[2]) return sp.hstack((-D21, D12, O3))
def _edgeCurlStencilx(self): n = self.vnC # The number of cell centers in each direction D32 = kron3(ddx(n[2]), speye(n[1]), speye(n[0] + 1)) D23 = kron3(speye(n[2]), ddx(n[1]), speye(n[0] + 1)) # O1 = spzeros(np.shape(D32)[0], np.shape(D31)[1]) O1 = spzeros((n[0] + 1) * n[1] * n[2], n[0] * (n[1] + 1) * (n[2] + 1)) return sp.hstack((O1, -D32, D23))
def _getInnerProductDerivFunction(self, tensorType, P, projType, v): """ :param numpy.ndarray prop: material property (tensor properties are possible) at each cell center (nC, (1, 3, or 6)) :param numpy.ndarray v: vector to multiply (required in the general implementation) :param list P: list of projection matrices :param str projType: 'F' for faces 'E' for edges :rtype: scipy.sparse.csr_matrix :return: dMdm, the derivative of the inner product matrix (n, nC*nA) """ assert projType in [ 'F', 'E' ], "projType must be 'F' for faces or 'E' for edges" n = getattr(self, 'n' + projType) if tensorType == -1: return None if v is None: raise Exception('v must be supplied for this implementation.') d = self.dim Z = spzeros(self.nC, self.nC) if tensorType == 0: dMdm = spzeros(n, 1) for i, p in enumerate(P): dMdm = dMdm + sp.csr_matrix( (p.T * (p * v), (range(n), np.zeros(n))), shape=(n, 1)) if d == 1: if tensorType == 1: dMdm = spzeros(n, self.nC) for i, p in enumerate(P): dMdm = dMdm + p.T * sdiag(p * v) elif d == 2: if tensorType == 1: dMdm = spzeros(n, self.nC) for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:] dMdm = dMdm + p.T * sp.vstack((sdiag(y1), sdiag(y2))) elif tensorType == 2: dMdms = [spzeros(n, self.nC) for _ in range(2)] for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:] dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z)) dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2))) dMdm = sp.hstack(dMdms) elif tensorType == 3: dMdms = [spzeros(n, self.nC) for _ in range(3)] for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:] dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z)) dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2))) dMdms[2] = dMdms[2] + p.T * sp.vstack( (sdiag(y2), sdiag(y1))) dMdm = sp.hstack(dMdms) elif d == 3: if tensorType == 1: dMdm = spzeros(n, self.nC) for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:self.nC * 2] y3 = Y[self.nC * 2:] dMdm = dMdm + p.T * sp.vstack( (sdiag(y1), sdiag(y2), sdiag(y3))) elif tensorType == 2: dMdms = [spzeros(n, self.nC) for _ in range(3)] for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:self.nC * 2] y3 = Y[self.nC * 2:] dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z, Z)) dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2), Z)) dMdms[2] = dMdms[2] + p.T * sp.vstack((Z, Z, sdiag(y3))) dMdm = sp.hstack(dMdms) elif tensorType == 3: dMdms = [spzeros(n, self.nC) for _ in range(6)] for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:self.nC * 2] y3 = Y[self.nC * 2:] dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z, Z)) dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2), Z)) dMdms[2] = dMdms[2] + p.T * sp.vstack((Z, Z, sdiag(y3))) dMdms[3] = dMdms[3] + p.T * sp.vstack( (sdiag(y2), sdiag(y1), Z)) dMdms[4] = dMdms[4] + p.T * sp.vstack( (sdiag(y3), Z, sdiag(y1))) dMdms[5] = dMdms[5] + p.T * sp.vstack( (Z, sdiag(y3), sdiag(y2))) dMdm = sp.hstack(dMdms) return dMdm
def _getInterpolationMat( self, loc, location_type="cell_centers", zeros_outside=False ): """Produces interpolation matrix Parameters ---------- loc : numpy.ndarray Location of points to interpolate to location_type: str, optional What to interpolate location_type can be:: 'Ex', 'edges_x' -> x-component of field defined on x edges 'Ey', 'edges_y' -> y-component of field defined on y edges 'Ez', 'edges_z' -> z-component of field defined on z edges 'Fx', 'faces_x' -> x-component of field defined on x faces 'Fy', 'faces_y' -> y-component of field defined on y faces 'Fz', 'faces_z' -> z-component of field defined on z faces 'N', 'nodes' -> scalar field defined on nodes 'CC', 'cell_centers' -> scalar field defined on cell centers 'CCVx', 'cell_centers_x' -> x-component of vector field defined on cell centers 'CCVy', 'cell_centers_y' -> y-component of vector field defined on cell centers 'CCVz', 'cell_centers_z' -> z-component of vector field defined on cell centers Returns ------- scipy.sparse.csr_matrix M, the interpolation matrix """ loc = as_array_n_by_dim(loc, self.dim) if not zeros_outside: if not np.all(self.is_inside(loc)): raise ValueError("Points outside of mesh") else: indZeros = np.logical_not(self.is_inside(loc)) loc[indZeros, :] = np.array([v.mean() for v in self.get_tensor("CC")]) location_type = self._parse_location_type(location_type) if location_type in [ "faces_x", "faces_y", "faces_z", "edges_x", "edges_y", "edges_z", ]: ind = {"x": 0, "y": 1, "z": 2}[location_type[-1]] if self.dim < ind: raise ValueError("mesh is not high enough dimension.") if "f" in location_type.lower(): items = (self.nFx, self.nFy, self.nFz)[: self.dim] else: items = (self.nEx, self.nEy, self.nEz)[: self.dim] components = [spzeros(loc.shape[0], n) for n in items] components[ind] = interpolation_matrix(loc, *self.get_tensor(location_type)) # remove any zero blocks (hstack complains) components = [comp for comp in components if comp.shape[1] > 0] Q = sp.hstack(components) elif location_type in ["cell_centers", "nodes"]: Q = interpolation_matrix(loc, *self.get_tensor(location_type)) elif location_type in ["cell_centers_x", "cell_centers_y", "cell_centers_z"]: Q = interpolation_matrix(loc, *self.get_tensor("CC")) Z = spzeros(loc.shape[0], self.nC) if location_type[-1] == "x": Q = sp.hstack([Q, Z, Z]) elif location_type[-1] == "y": Q = sp.hstack([Z, Q, Z]) elif location_type[-1] == "z": Q = sp.hstack([Z, Z, Q]) else: raise NotImplementedError( "getInterpolationMat: location_type==" + location_type + " and mesh.dim==" + str(self.dim) ) if zeros_outside: Q[indZeros, :] = 0 return Q.tocsr()
def _getInterpolationMat(self, loc, locType='CC', zerosOutside=False): """ Produces interpolation matrix :param numpy.ndarray loc: Location of points to interpolate to :param str locType: What to interpolate (see below) :rtype: scipy.sparse.csr_matrix :return: M, the interpolation matrix locType can be:: 'Ex' -> x-component of field defined on edges 'Ey' -> y-component of field defined on edges 'Ez' -> z-component of field defined on edges 'Fx' -> x-component of field defined on faces 'Fy' -> y-component of field defined on faces 'Fz' -> z-component of field defined on faces 'N' -> scalar field defined on nodes 'CC' -> scalar field defined on cell centers 'CCVx' -> x-component of vector field defined on cell centers 'CCVy' -> y-component of vector field defined on cell centers 'CCVz' -> z-component of vector field defined on cell centers """ loc = utils.asArray_N_x_Dim(loc, self.dim) if zerosOutside is False: assert np.all(self.isInside(loc)), "Points outside of mesh" else: indZeros = np.logical_not(self.isInside(loc)) loc[indZeros, :] = np.array([ v.mean() for v in self.getTensor('CC') ]) if locType in ['Fx', 'Fy', 'Fz', 'Ex', 'Ey', 'Ez']: ind = {'x': 0, 'y': 1, 'z': 2}[locType[1]] assert self.dim >= ind, 'mesh is not high enough dimension.' nF_nE = self.vnF if 'F' in locType else self.vnE components = [utils.spzeros(loc.shape[0], n) for n in nF_nE] components[ind] = utils.interpmat(loc, *self.getTensor(locType)) # remove any zero blocks (hstack complains) components = [comp for comp in components if comp.shape[1] > 0] Q = sp.hstack(components) elif locType in ['CC', 'N']: Q = utils.interpmat(loc, *self.getTensor(locType)) elif locType in ['CCVx', 'CCVy', 'CCVz']: Q = utils.interpmat(loc, *self.getTensor('CC')) Z = utils.spzeros(loc.shape[0], self.nC) if locType == 'CCVx': Q = sp.hstack([Q, Z, Z]) elif locType == 'CCVy': Q = sp.hstack([Z, Q, Z]) elif locType == 'CCVz': Q = sp.hstack([Z, Z, Q]) else: raise NotImplementedError( 'getInterpolationMat: locType==' + locType + ' and mesh.dim==' + str(self.dim) ) if zerosOutside: Q[indZeros, :] = 0 return Q.tocsr()
def _getInnerProductDerivFunction(self, tensorType, P, projection_type, v): """ Parameters ---------- model : numpy.ndarray material property (tensor properties are possible) at each cell center (nC, (1, 3, or 6)) v : numpy.ndarray vector to multiply (required in the general implementation) P : list list of projection matrices projection_type : str 'F' for faces 'E' for edges Returns ------- scipy.sparse.csr_matrix dMdm, the derivative of the inner product matrix (n, nC*nA) """ if projection_type not in ["F", "E"]: raise TypeError( "projection_type must be 'F' for faces or 'E' for edges") n = getattr(self, "n" + projection_type) if tensorType == -1: return None if v is None: raise Exception("v must be supplied for this implementation.") d = self.dim Z = spzeros(self.nC, self.nC) if tensorType == 0: dMdm = spzeros(n, 1) for i, p in enumerate(P): dMdm = dMdm + sp.csr_matrix( (p.T * (p * v), (range(n), np.zeros(n))), shape=(n, 1)) if d == 1: if tensorType == 1: dMdm = spzeros(n, self.nC) for i, p in enumerate(P): dMdm = dMdm + p.T * sdiag(p * v) elif d == 2: if tensorType == 1: dMdm = spzeros(n, self.nC) for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:] dMdm = dMdm + p.T * sp.vstack((sdiag(y1), sdiag(y2))) elif tensorType == 2: dMdms = [spzeros(n, self.nC) for _ in range(2)] for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:] dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z)) dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2))) dMdm = sp.hstack(dMdms) elif tensorType == 3: dMdms = [spzeros(n, self.nC) for _ in range(3)] for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:] dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z)) dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2))) dMdms[2] = dMdms[2] + p.T * sp.vstack( (sdiag(y2), sdiag(y1))) dMdm = sp.hstack(dMdms) elif d == 3: if tensorType == 1: dMdm = spzeros(n, self.nC) for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:self.nC * 2] y3 = Y[self.nC * 2:] dMdm = dMdm + p.T * sp.vstack( (sdiag(y1), sdiag(y2), sdiag(y3))) elif tensorType == 2: dMdms = [spzeros(n, self.nC) for _ in range(3)] for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:self.nC * 2] y3 = Y[self.nC * 2:] dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z, Z)) dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2), Z)) dMdms[2] = dMdms[2] + p.T * sp.vstack((Z, Z, sdiag(y3))) dMdm = sp.hstack(dMdms) elif tensorType == 3: dMdms = [spzeros(n, self.nC) for _ in range(6)] for i, p in enumerate(P): Y = p * v y1 = Y[:self.nC] y2 = Y[self.nC:self.nC * 2] y3 = Y[self.nC * 2:] dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z, Z)) dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2), Z)) dMdms[2] = dMdms[2] + p.T * sp.vstack((Z, Z, sdiag(y3))) dMdms[3] = dMdms[3] + p.T * sp.vstack( (sdiag(y2), sdiag(y1), Z)) dMdms[4] = dMdms[4] + p.T * sp.vstack( (sdiag(y3), Z, sdiag(y1))) dMdms[5] = dMdms[5] + p.T * sp.vstack( (Z, sdiag(y3), sdiag(y2))) dMdm = sp.hstack(dMdms) return dMdm