Exemplo n.º 1
0
 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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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()
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    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