Esempio n. 1
0
def collapse(bmat):
    '''Collapse what are blocks of bmat'''
    # Single block cases
    # Do nothing
    if is_petsc_mat(bmat) or is_number(bmat) or is_petsc_vec(bmat):
        return bmat

    # Multiplication
    if isinstance(bmat, block_mul):
        return collapse_mul(bmat)
    # +
    elif isinstance(bmat, block_add):
        return collapse_add(bmat)
    # -
    elif isinstance(bmat, block_sub):
        return collapse_sub(bmat)
    # T
    elif isinstance(bmat, block_transpose):
        return collapse_tr(bmat)
    # Some things in cbc.block know their matrix representation
    # E.g. InvLumpDiag...
    elif hasattr(bmat, 'A'):
        assert is_petsc_mat(bmat.A)
        return bmat.A

    raise ValueError('Do not know how to collapse %r' % type(bmat))
Esempio n. 2
0
def get_dims(thing):
    '''
    Size of Rn vector or operator Rn to Rm. We return None for scalars
    and raise when such an operator cannot be established, i.e. there 
    are consistency checks going on 
    '''
    if is_petsc_vec(thing): return thing.size()

    if is_petsc_mat(thing): return (thing.size(0), thing.size(1))

    if is_number(thing): return None

    # Now let's handdle block stuff
    # Multiplication
    if isinstance(thing, block_mul):
        A, B = thing.chain[0], thing.chain[1:]

        dims_A, dims_B = get_dims(A), get_dims(B[0])
        # A number does not change
        if dims_A is None:
            return dims_B
        if dims_B is None:
            return dims_A
        # Otherwise, consistency
        if len(B) == 1:
            assert len(dims_A) == len(dims_B)
            assert dims_A[1] == dims_B[0]
            return (dims_A[0], dims_B[1])
        else:
            dims_B = get_dims(reduce(operator.mul, B))

            assert len(dims_A) == len(dims_B)
            assert dims_A[1] == dims_B[0]
            return (dims_A[0], dims_B[1])
    # +, -
    elif isinstance(thing, (block_add, block_sub)):
        A, B = thing.A, thing.B
        if is_number(A):
            return get_dims(B)

        if is_number(B):
            return get_dims(A)

        dims = get_dims(A)
        assert dims == get_dims(B), (dims, get_dims(B))
        return dims
    # T
    elif isinstance(thing, block_transpose):
        dims = get_dims(thing.A)
        return (dims[1], dims[0])
    # Some things in cbc.block know their matrix representation
    # E.g. InvLumpDiag...
    elif hasattr(thing, 'A'):
        assert is_petsc_mat(thing.A)
        return get_dims(thing.A)

    raise ValueError('Cannot get_dims of %r, %s' % (type(thing), thing))
Esempio n. 3
0
def collapse(bmat):
    '''Collapse what are blocks of bmat'''
    # Single block cases
    # Do nothing
    if is_petsc_mat(bmat) or is_number(bmat) or is_petsc_vec(bmat):
        return bmat

    if isinstance(bmat, (Vector, Matrix, GenericVector)):
        return bmat

    # Multiplication
    if isinstance(bmat, block_mul):
        return collapse_mul(bmat)
    # +
    elif isinstance(bmat, block_add):
        return collapse_add(bmat)
    # -
    elif isinstance(bmat, block_sub):
        return collapse_sub(bmat)
    # T
    elif isinstance(bmat, block_transpose):
        return collapse_tr(bmat)

    # Some things in cbc.block know their matrix representation
    # This is typically diagonals like InvLumpDiag etc
    elif hasattr(bmat, 'v'):
        # So now we make that diagonal matrix
        diagonal = bmat.v

        n = diagonal.size
        mat = PETSc.Mat().createAIJ(comm=COMM, size=[[n, n], [n, n]], nnz=1)
        mat.assemblyBegin()
        mat.setDiagonal(diagonal)
        mat.assemblyEnd()

        return PETScMatrix(mat)
    # Some operators actually have matrix repre (HsMG)
    elif hasattr(bmat, 'matrix'):
        return bmat.matrix

    # Try:
    elif hasattr(bmat, 'collapse'):
        return bmat.collapse()
    
    elif hasattr(bmat, 'create_vec'):
        x = bmat.create_vec()
        columns = []
        for ei in Rn_basis(x):
            y = bmat*ei
            columns.append(csr_matrix(convert(y).get_local()))
        bmat = (sp_vstack(columns).T).tocsr()

        return numpy_to_petsc(bmat)
    
    raise ValueError('Do not know how to collapse %r' % type(bmat))
Esempio n. 4
0
def collapse(bmat):
    '''Collapse what are blocks of bmat'''
    # Single block cases
    # Do nothing
    if is_petsc_mat(bmat) or is_number(bmat) or is_petsc_vec(bmat):
        return bmat

    if isinstance(bmat, (Vector, Matrix, GenericVector)):
        return bmat

    # Multiplication
    if isinstance(bmat, block_mul):
        return collapse_mul(bmat)
    # +
    elif isinstance(bmat, block_add):
        return collapse_add(bmat)
    # -
    elif isinstance(bmat, block_sub):
        return collapse_sub(bmat)
    # T
    elif isinstance(bmat, block_transpose):
        return collapse_tr(bmat)
    # Some things in cbc.block know their matrix representation
    # This is typically diagonals like InvLumpDiag etc
    elif hasattr(bmat, 'v'):
        # So now we make that diagonal matrix
        diagonal = bmat.v

        n = diagonal.size
        mat = PETSc.Mat().createAIJ(comm=COMM, size=[[n, n], [n, n]], nnz=1)
        mat.assemblyBegin()
        mat.setDiagonal(diagonal)
        mat.assemblyEnd()

        return PETScMatrix(mat)
    # Some operators actually have matrix repre (HsMG)
    elif hasattr(bmat, 'matrix'):
        return bmat.matrix

    raise ValueError('Do not know how to collapse %r' % type(bmat))
Esempio n. 5
0
def collapse(bmat):
    '''Collapse what are blocks of bmat'''
    # Single block cases
    # Do nothing
    if is_petsc_mat(bmat) or is_number(bmat) or is_petsc_vec(bmat):
        return bmat

    if isinstance(bmat, (Vector, Matrix, GenericVector)):
        return bmat

    # Multiplication
    if isinstance(bmat, block_mul):
        return collapse_mul(bmat)
    # +
    elif isinstance(bmat, block_add):
        return collapse_add(bmat)
    # -
    elif isinstance(bmat, block_sub):
        return collapse_sub(bmat)
    # T
    elif isinstance(bmat, block_transpose):
        return collapse_tr(bmat)
    # Some things in cbc.block know their matrix representation
    # This is typically diagonals like InvLumpDiag etc
    elif hasattr(bmat, 'v'):
        # So now we make that diagonal matrix
        diagonal = bmat.v

        n = diagonal.size
        mat = PETSc.Mat().createAIJ(comm=COMM, size=[[n, n], [n, n]], nnz=1)
        mat.assemblyBegin()
        mat.setDiagonal(diagonal)
        mat.assemblyEnd()

        return PETScMatrix(mat)
    # Some operators actually have matrix repre (HsMG)
    elif hasattr(bmat, 'matrix'):
        return bmat.matrix

    raise ValueError('Do not know how to collapse %r' % type(bmat))
Esempio n. 6
0
def get_dims(thing):
    '''
    Size of Rn vector or operator Rn to Rm. We return None for scalars
    and raise when such an operator cannot be established, i.e. there 
    are consistency checks going on 
    '''
    if is_petsc_vec(thing): return thing.size()

    if is_petsc_mat(thing): return (thing.size(0), thing.size(1))
    
    if is_number(thing): return None
    
    # Now let's handdle block stuff
    # Multiplication
    if isinstance(thing, block_mul):
        A, B = thing.chain[0], thing.chain[1:]

        dims_A, dims_B = get_dims(A), get_dims(B[0])
        # A number does not change
        if dims_A is None:
            return dims_B
        if dims_B is None:
            return dims_A
        # Otherwise, consistency
        if len(B) == 1:
            assert len(dims_A) == len(dims_B) 
            assert dims_A[1] == dims_B[0], (dims_A, dims_B) 
            return (dims_A[0], dims_B[1])
        else:
            dims_B = get_dims(reduce(operator.mul, B))
            
            assert len(dims_A) == len(dims_B) 
            assert dims_A[1] == dims_B[0], (dims_A, dims_B)
            return (dims_A[0], dims_B[1])
    # +, -
    if isinstance(thing, (block_add, block_sub)):
        A, B = thing.A, thing.B
        if is_number(A):
            return get_dims(B)

        if is_number(B):
            return get_dims(A)

        dims = get_dims(A)
        assert dims == get_dims(B), (dims, get_dims(B))
        return dims
    # T
    if isinstance(thing, block_transpose):
        dims = get_dims(thing.A)
        return (dims[1], dims[0])
    
    # Some things in cbc.block know their maE.g. InvLumpDiag...Almost last resort
    if hasattr(thing, 'A'):
        assert is_petsc_mat(thing.A)
        return get_dims(thing.A)

    if hasattr(thing, '__sizes__'):
        return thing.__sizes__
    
    if hasattr(thing, 'create_vec'):
        return (thing.create_vec(0).size(), thing.create_vec(1).size())

    raise ValueError('Cannot get_dims of %r, %s' % (type(thing), thing))