def get_mfem_sparsemat(self): ''' generate mfem::SparseMatrix using the same data ''' if np.iscomplexobj(self): csr_r = self.tocsr().real csr_r.eliminate_zeros() csr_i = self.tocsr().imag csr_i.eliminate_zeros() return mfem.SparseMatrix(csr_r), mfem.SparseMatrix(csr_i) else: csr_r = self.tocsr() csr_r.eliminate_zeros() csr_i = None return mfem.SparseMatrix(csr_r), None
def schur(*names, **kwargs): # schur("A1", "B1", scale=(1.0, 1e3)) prc = kwargs.pop('prc') blockname = kwargs.pop('blockname') r0 = prc.get_row_by_name(blockname) c0 = prc.get_col_by_name(blockname) scales = kwargs.pop('scale', [1] * len(names)) print_level = kwargs.pop('print_level', -1) S = [] for name, scale in zip(names, scales): r1 = prc.get_row_by_name(name) c1 = prc.get_col_by_name(name) B = prc.get_operator_block(r0, c1) Bt = prc.get_operator_block(r1, c0) B0 = prc.get_operator_block(r1, c1) if use_parallel: Bt = Bt.Transpose() Bt = Bt.Transpose() Md = mfem.HypreParVector(MPI.COMM_WORLD, B0.GetGlobalNumRows(), B0.GetColStarts()) else: Bt = Bt.Copy() Md = mfem.Vector() B0.GetDiag(Md) Md *= scale if use_parallel: Bt.InvScaleRows(Md) S.append(mfem.ParMult(B, Bt)) else: S.append(mfem.Mult(B, Bt)) if use_parallel: from mfem.common.parcsr_extra import ToHypreParCSR, ToScipyCoo S2 = [ToScipyCoo(s) for s in S] for s in S2[1:]: S2[0] = S2[0] + s S = ToHypreParCSR(S2[0].tocsr()) invA0 = mfem.HypreBoomerAMG(S) else: from mfem.common.sparse_utils import sparsemat_to_scipycsr S2 = [sparsemat_to_scipycsr(s).tocoo() for s in S] for s in S2[1:]: S2[0] = S2[0] + s S = mfem.SparseMatrix(S2.tocsr()) invA0 = mfem.DSmoother(S) invA0.iterative_mode = False invA0.SetPrintLevel(print_level) invA0._S = S return invA0
def run_test(): print("Test sparsemat module") indptr = np.array([0, 2, 3, 6], dtype=np.int32) indices = np.array([0, 2, 2, 0, 1, 2], dtype=np.int32) data = np.array([1, 2, 3, 4, 5, 6], dtype=float) mat = mfem.SparseMatrix([indptr, indices, data, 3, 3]) mat.Print() mat.PrintInfo()
def get_global_blkmat_interleave(self): ''' This routine ordered unkonws in the following order Re FFE1, Im FES1, ReFES2, Im FES2, ... If self.complex is False, it assembles a nomal block matrix FES1, FES2... ''' roffsets, coffsets = self.get_local_partitioning(convert_real=True, interleave=True) dprint1("offsets", roffsets, coffsets) ro = mfem.intArray(list(roffsets)) co = mfem.intArray(list(coffsets)) glcsr = mfem.BlockOperator(ro, co) ii = 0 for i in range(self.shape[0]): jj = 0 for j in range(self.shape[1]): if self[i, j] is not None: if use_parallel: if isinstance(self[i, j], chypre.CHypreMat): gcsr = self[i, j] cp = self[i, j].GetColPartArray() rp = self[i, j].GetRowPartArray() s = self[i, j].shape #if (cp == rp).all() and s[0] == s[1]: if gcsr[0] is not None: csr = ToScipyCoo(gcsr[0]).tocsr() gcsr[0] = ToHypreParCSR(csr, col_starts=cp) if gcsr[1] is not None: csr = ToScipyCoo(gcsr[1]).tocsr() gcsr[1] = ToHypreParCSR(csr, col_starts=cp) gcsrm = ToHypreParCSR(-csr, col_starts=cp) dprint2(i, j, s, rp, cp) else: assert False, "unsupported block element " + str( type(self[i, j])) else: if isinstance(self[i, j], ScipyCoo): gcsr = self[i, j].get_mfem_sparsemat() if gcsr[1] is not None: gcsrm = mfem.SparseMatrix(gcsr[1]) gcsrm *= -1. else: assert False, "unsupported block element " + type( self[i, j]) glcsr.SetBlock(ii, jj, gcsr[0]) if self.complex: glcsr.SetBlock(ii + 1, jj + 1, gcsr[0]) if gcsr[1] is not None: glcsr.SetBlock(ii + 1, jj, gcsr[1]) glcsr.SetBlock(ii, jj + 1, gcsrm) jj = jj + 2 if self.complex else jj + 1 ii = ii + 2 if self.complex else ii + 1 return glcsr
def get_global_blkmat_merged(self, symmetric=False): ''' This routine ordered unkonws in the following order Re FFE1, Im FES1, ReFES2, Im FES2, ... matrix FES1, FES2... ''' assert self.complex, "this format is complex only" roffsets, coffsets = self.get_local_partitioning() roffsets = np.sum(np.diff(roffsets).reshape(-1, 2), 1) coffsets = np.sum(np.diff(coffsets).reshape(-1, 2), 1) roffsets = np.hstack([0, np.cumsum(roffsets)]) coffsets = np.hstack([0, np.cumsum(coffsets)]) dprint1("Generating MFEM BlockMatrix: shape = " + str((len(roffsets) - 1, len(coffsets) - 1))) dprint1("Generating MFEM BlockMatrix: roffset/coffset = ", roffsets, coffsets) ro = mfem.intArray(list(roffsets)) co = mfem.intArray(list(coffsets)) glcsr = mfem.BlockOperator(ro, co) ii = 0 for j in range(self.shape[1]): jfirst = True for i in range(self.shape[0]): if self[i, j] is not None: if use_parallel: if isinstance(self[i, j], chypre.CHypreMat): gcsr = self[i, j] cp = self[i, j].GetColPartArray() rp = self[i, j].GetRowPartArray() rsize_local = rp[1] - rp[0] if jfirst: csize_local = cp[1] - cp[0] csize = allgather(csize_local) cstarts = np.hstack([0, np.cumsum(csize)]) jfirst = False s = self[i, j].shape # if (cp == rp).all() and s[0] == s[1]: ''' if gcsr[0] is not None: csc = ToScipyCoo(gcsr[0]).tocsc() csc1 = [csc[:,cstarts[k]:cstarts[k+1]] for k in range(len(cstarts)-1)] if symmetric: csc1m = [-csc[:,cstarts[k]:cstarts[k+1]] for k in range(len(cstarts)-1)] else: csc1 = [None]*len(csize) csc1m = [None]*len(csize) if gcsr[1] is not None: csc = ToScipyCoo(gcsr[1]).tocsc() if not symmetric: csc2 = [ csc[:,cstarts[k]:cstarts[k+1]] for k in range(len(cstarts)-1)] csc2m = [-csc[:,cstarts[k]:cstarts[k+1]] for k in range(len(cstarts)-1)] else: csc2 = [None]*len(csize) csc2m = [None]*len(csize) if symmetric: csr = scipy.sparse.bmat([sum(zip(csc1, csc2m), ()), sum(zip(csc2m, csc1m), ())]).tocsr() else: csr = scipy.sparse.bmat([sum(zip(csc1, csc2m), ()), sum(zip(csc2, csc1), ())]).tocsr() cp2 = [(cp*2)[0], (cp*2)[1], np.sum(csize)*2] #gcsr[1] = ToHypreParCSR(csr, col_starts =cp) gcsr = ToHypreParCSR(csr, col_starts =cp2) ''' if gcsr[0] is None: csr = scipy.sparse.csr_matrix( (rsize_local, cstarts[-1]), dtype=np.float64) cp3 = [cp[0], cp[1], cstarts[-1]] gcsa = ToHypreParCSR(csr, col_starts=cp3) else: gcsa = gcsr[0] if gcsr[1] is None: csr = scipy.sparse.csr_matrix( (rsize_local, cstarts[-1]), dtype=np.float64) cp3 = [cp[0], cp[1], cstarts[-1]] gcsb = ToHypreParCSR(csr, col_starts=cp3) else: gcsb = gcsr[1] else: assert False, "unsupported block element " + \ str(type(self[i, j])) else: if isinstance(self[i, j], ScipyCoo): ''' if symmetric: tmp = scipy.sparse.bmat([[ self[i, j].real, -self[i, j].imag], [-self[i, j].imag, -self[i, j].real]]) else: tmp = scipy.sparse.bmat([[self[i, j].real, -self[i, j].imag], [self[i, j].imag, self[i, j].real]]) ''' csra = self[i, j].real.tocsr() csrb = self[i, j].imag.tocsr() csra.eliminate_zeros() csrb.eliminate_zeros() gcsa = mfem.SparseMatrix(csra) gcsb = mfem.SparseMatrix(csrb) else: assert False, "unsupported block element " + \ type(self[i, j]) Hermitian = False if symmetric else True gcsr = mfem.ComplexOperator(gcsa, gcsb, False, False, Hermitian) gcsr._real_operator = gcsa gcsr._imag_operator = gcsb glcsr.SetBlock(i, j, gcsr) return glcsr