コード例 #1
0
ファイル: convert.py プロジェクト: MiroK/fenics_ii
def convert(bmat, algorithm='numpy'):
    '''
    Attempt to convert bmat to a PETSc(Matrix/Vector) object.
    If succed this is at worst a number.
    '''
    # Block vec conversion
    if isinstance(bmat, block_vec):
        array = block_vec_to_numpy(bmat)
        vec = PETSc.Vec().createWithArray(array)
        vec.assemble()
        return PETScVector(vec)
    
    # Conversion of bmat is bit more involved because of the possibility
    # that some of the blocks are numbers or composition of matrix operations
    if isinstance(bmat, block_mat):
        # Create collpsed bmat
        row_sizes, col_sizes = bmat_sizes(bmat)
        nrows, ncols = len(row_sizes), len(col_sizes)
        indices = itertools.product(list(range(nrows)), list(range(ncols)))

        blocks = np.zeros((nrows, ncols), dtype='object')
        for block, (i, j) in zip(bmat.blocks.flatten(), indices):
            # This might is guaranteed to be matrix or number
            A = collapse(block)

            if is_number(A):
                # Diagonal matrices can be anything provided square
                if i == j and row_sizes[i] == col_sizes[j]:
                    A = diagonal_matrix(row_sizes[i], A)
                else:
                    # Offdiagonal can only be zero
                    A = zero_matrix(row_sizes[i], col_sizes[j])
                #else:
                #    A = 0
            # The converted block
            blocks[i, j] = A
        # Now every block is a matrix/number and we can make a monolithic thing
        bmat = block_mat(blocks)

        assert all(is_petsc_mat(block) or is_number(block)
                   for block in bmat.blocks.flatten())
        
        # Opt out of monolithic
        if not algorithm:
            set_lg_map(bmat)
            return bmat
        
        # Monolithic via numpy (fast)
        # Convert to numpy
        array = block_mat_to_numpy(bmat)
        # Constuct from numpy
        bmat = numpy_to_petsc(array)
        set_lg_map(bmat)

        return bmat

    # Try with a composite
    return collapse(bmat)
コード例 #2
0
    def collapse(self):
        '''Explicit matrix representation of the operator'''
        from xii.linalg.matrix_utils import diagonal_matrix, row_matrix
        from xii import ii_convert

        D = row_matrix(self.dual_basis)
        B = row_matrix(self.primal_basis)
        I = diagonal_matrix(B.size(1), 1.)
        return ii_convert(I - B.T * D)
コード例 #3
0
ファイル: convert.py プロジェクト: HomaiRS/fenics_ii
def convert(bmat, algorithm='numpy'):
    '''
    Attempt to convert bmat to a PETSc(Matrix/Vector) object.
    If succed this is at worst a number.
    '''
    # Block vec conversion
    if isinstance(bmat, block_vec):
        array = block_vec_to_numpy(bmat)
        vec = PETSc.Vec().createWithArray(array)
        vec.assemble()
        return PETScVector(vec)
    
    # Conversion of bmat is bit more involved because of the possibility
    # that some of the blocks are numbers or composition of matrix operations
    if isinstance(bmat, block_mat):
        # Create collpsed bmat
        row_sizes, col_sizes = bmat_sizes(bmat)
        nrows, ncols = len(row_sizes), len(col_sizes)
        indices = itertools.product(range(nrows), range(ncols))
        
        blocks = np.zeros((nrows, ncols), dtype='object')
        for block, (i, j) in zip(bmat.blocks.flatten(), indices):
            # This might is guaranteed to be matrix or number
            A = collapse(block)

            if is_number(A):
                # Diagonal matrices can be anything provided square
                if i == j and row_sizes[i] == col_sizes[j]:
                    A = diagonal_matrix(row_sizes[i], A)
                else:
                    # Offdiagonal can only be zero
                    A = zero_matrix(row_sizes[i], col_sizes[j])
                #else:
                #    A = 0
            # The converted block
            blocks[i, j] = A
        # Now every block is a matrix/number and we can make a monolithic thing
        bmat = block_mat(blocks)

        assert all(is_petsc_mat(block) or is_number(block)
                   for block in bmat.blocks.flatten())
        
        # Opt out of monolithic
        if not algorithm: return bmat
        
        # Monolithic via numpy (fast)
        # Convert to numpy
        array = block_mat_to_numpy(bmat)
        # Constuct from numpy
        return numpy_to_petsc(array)

    # Try with a composite
    return collapse(bmat)
コード例 #4
0
ファイル: nest.py プロジェクト: MiroK/fenics_ii
def pc_mat(pc, block):
    '''Set pc for (non-block) operator'''
    if isinstance(block, LU):
        pc.setType('lu')
        pc.setFactorPivot(1E-18)
        return block.A

    if isinstance(block, SUPERLU_LU):
        pc.setType('lu')
        pc.setFactorPivot(1E-18)
        pc.setFactorSolverType('superlu')
        return block.A

    if isinstance(block, AMG):
        pc.setType('hypre')
        return block.A

    if isinstance(block, Elasticity):
        pc.setType('gamg')
        return block.A

    # FIXME: Very add hoc support for sum, this should recursive
    if isinstance(block, block_add):
        this, that = block.A, block.B
        assert isinstance(this, precond) and isinstance(that, precond)

        pc.setType('composite')
        pc.setCompositeType(PETSc.PC.CompositeType.ADDITIVE)

        for sub, op in enumerate((this, that)):
            # Fake it
            pc_ = PETSc.PC().create()
            A = pc_mat(pc_, op)

            pc.addCompositePC(pc_.getType())

            pc_sub = pc.getCompositePC(sub)
            # Make it
            pc_mat(pc_sub, op)
            pc_sub.setOperators(as_petsc(A))

        mat = diagonal_matrix(op.A.size(0), 1)

        return mat

    assert False, type(block)