def BF2PyMat(rbf, ibf=None, finalize=False): ''' Convert pair of BilinearForms to CHypreMat or ScipySparsematrix ''' if finalize: rbf.Finalize() if ibf is not None: ibf.Finalize() if MFEM_PAR: M1 = rbf.ParallelAssemble() M1.thisown = True if ibf is not None: M2 = ibf.ParallelAssemble() M2.thisown = True else: M2 = None return CHypreMat(M1, M2) else: from mfem.common.sparse_utils import sparsemat_to_scipycsr M1 = rbf.SpMat() if ibf is None: return sparsemat_to_scipycsr(M1, dtype=float) if ibf is not None: M2 = ibf.SpMat() m1 = sparsemat_to_scipycsr(M1, dtype=float).tolil() m2 = sparsemat_to_scipycsr(M2, dtype=complex).tolil() m = m1 + 1j * m2 m = m.tocsr() return m
def SetOperator(self, opr): def isSparseMatrix(opr): return isinstance(opr, mfem.SparseMatrix) check = opr._real_operator if isinstance(opr, mfem.ComplexOperator) else opr if isSparseMatrix(check): from mfem.common.sparse_utils import sparsemat_to_scipycsr if isinstance(opr, mfem.ComplexOperator): mat = (sparsemat_to_scipycsr(opr._real_operator, float) + sparsemat_to_scipycsr(opr._imag_operator, float) * 1j) coo_opr = mat.tocoo() self.is_complex_operator = True else: coo_opr = sparsemat_to_scipycsr(opr, float).tocoo() self.solver = MUMPSSolver(self.gui, self.engine) self.solver.AllocSolver(self.is_complex_operator, self.gui.use_single_precision) self.solver.SetOperator(coo_opr, False) self.solver.keep_sol_distributed = True self.row_part = [-1, -1] else: from mfem.common.parcsr_extra import ToScipyCoo from scipy.sparse import coo_matrix if isinstance(opr, mfem.ComplexOperator): lcsr = (ToScipyCoo(opr._real_operator).tocsr() + ToScipyCoo(opr._imag_operator).tocsr() * 1j) lcoo = lcsr.tocoo() shape = (opr._real_operator.GetGlobalNumRows(), opr._real_operator.GetGlobalNumCols()) rpart = opr._real_operator.GetRowPartArray() self.is_complex_operator = True self.row_part = rpart else: lcoo = ToScipyCoo(opr) shape = (opr.GetGlobalNumRows(), opr.GetGlobalNumCols()) rpart = opr.GetRowPartArray() self.row_part = rpart gcoo = coo_matrix(shape) gcoo.data = lcoo.data gcoo.row = lcoo.row + rpart[0] gcoo.col = lcoo.col self.solver = MUMPSSolver(self.gui, self.engine) self.solver.AllocSolver(self.is_complex_operator, self.gui.use_single_precision) self.solver.SetOperator(gcoo, True) self.solver.keep_sol_distributed = True self.is_parallel = True self.solver.set_silent(self.silent)
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 MfemMat2PyMat(M1, M2=None): ''' Convert pair of SpMat/HypreParCSR to CHypreMat or ScipySparsematrix. This is simpler version of BF2PyMat, only difference is it skippes convertion from BF to Matrix. ''' from mfem.common.sparse_utils import sparsemat_to_scipycsr if MFEM_PAR: return CHypreMat(M1, M2) else: if M2 is None: return sparsemat_to_scipycsr(M1, dtype=float) else: m1 = sparsemat_to_scipycsr(M1, dtype=float).tolil() m2 = sparsemat_to_scipycsr(M2, dtype=complex).tolil() m = m1 + 1j * m2 m = m.tocsr() return m