Example #1
0
 def _jacobian_matrix_assemble(self, jacobian_matrix_input: GenericMatrix, petsc_jacobian: PETSc.Mat):
     self.jacobian_matrix = PETScMatrix(petsc_jacobian)
     self.jacobian_matrix.zero()
     self.jacobian_matrix += jacobian_matrix_input
     # Make sure to keep nonzero pattern, as dolfin does by default, because this option is apparently
     # not preserved by the sum
     petsc_jacobian.setOption(PETSc.Mat.Option.KEEP_NONZERO_PATTERN, True)
Example #2
0
def avg_mat(V, TV, reduced_mesh, data):
    '''
    A mapping for computing the surface averages of function in V in the 
    space TV. Surface averaging is defined as 

    (Pi u)(x) = |C_R(x)|int_{C_R(x)} u(y) dy with C_R(x) the circle of 
    radius R(x) centered at x with a normal parallel with the edge tangent.
    '''
    assert TV.mesh().id() == reduced_mesh.id()

    # It is most natural to represent Pi u in a DG space
    assert TV.ufl_element().family() == 'Discontinuous Lagrange'

    # Compatibility of spaces
    assert V.dolfin_element().value_rank() == TV.dolfin_element().value_rank()
    assert V.ufl_element().value_shape() == TV.ufl_element().value_shape()
    assert average_cell(V) == TV.mesh().ufl_cell()
    assert V.mesh().geometry().dim() == TV.mesh().geometry().dim()

    radius = data['radius']
    # 3d-1d trace
    if radius is None:
        return PETScMatrix(trace_3d1d_matrix(V, TV, reduced_mesh))

    quad_degree = data['quad_degree']
    # Surface averages
    if data['surface'] == 'cylinder':
        Rmat = cylinder_average_matrix(V, TV, radius, quad_degree)
    # The sphere
    else:
        Rmat = sphere_average_matrix(V, TV, radius, quad_degree)

    return PETScMatrix(Rmat)
Example #3
0
def collapse_mul(bmat):
    '''A*B*C to single matrix'''
    # A0 * A1 * ...
    A, B = bmat.chain[0], bmat.chain[1:]

    if len(B) == 1:
        B = B[0]
        # Two matrices
        if is_petsc_mat(A) and is_petsc_mat(B):
            A_ = as_petsc(A)
            B_ = as_petsc(B)
            assert A_.size[1] == B_.size[0]
            C_ = PETSc.Mat()
            A_.matMult(B_, C_)

            return PETScMatrix(C_)
        # One of them is a number
        elif is_petsc_mat(A) and is_number(B):
            A_ = as_petsc(A)
            C_ = A_.copy()
            C_.scale(B)
            return PETScMatrix(C_)

        elif is_petsc_mat(B) and is_number(A):
            B_ = as_petsc(B)
            C_ = B_.copy()
            C_.scale(A)
            return PETScMatrix(C_)
        # Some compositions
        else:
            return collapse(collapse(A) * collapse(B))
    # Recurse
    else:
        return collapse_mul(collapse(A) * collapse(reduce(operator.mul, B)))
Example #4
0
    def solve(self, mesh, num=5):
        """ Solve for num eigenvalues based on the mesh. """
        # conforming elements
        V = FunctionSpace(mesh, "CG", self.degree)
        u = TrialFunction(V)
        v = TestFunction(V)

        # weak formulation
        a = inner(grad(u), grad(v)) * dx
        b = u * v * ds
        A = PETScMatrix()
        B = PETScMatrix()
        A = assemble(a, tensor=A)
        B = assemble(b, tensor=B)

        # find eigenvalues
        eigensolver = SLEPcEigenSolver(A, B)
        eigensolver.parameters["spectral_transform"] = "shift-and-invert"
        eigensolver.parameters["problem_type"] = "gen_hermitian"
        eigensolver.parameters["spectrum"] = "smallest real"
        eigensolver.parameters["spectral_shift"] = 1.0E-10
        eigensolver.solve(num + 1)

        # extract solutions
        lst = [
            eigensolver.get_eigenpair(i)
            for i in range(1, eigensolver.get_number_converged())
        ]
        for k in range(len(lst)):
            u = Function(V)
            u.vector()[:] = lst[k][2]
            lst[k] = (lst[k][0], u)  # pair (eigenvalue,eigenfunction)
        return np.array(lst)
Example #5
0
def test_nest_matrix(pushpop_parameters):

    # Create Matrices and insert into nest
    A00 = PETScMatrix()
    A01 = PETScMatrix()
    A10 = PETScMatrix()
    mesh = UnitSquareMesh(12, 12)
    V = FunctionSpace(mesh, "Lagrange", 2)
    Q = FunctionSpace(mesh, "Lagrange", 1)
    u, v = TrialFunction(V), TestFunction(V)
    p, q = TrialFunction(Q), TestFunction(Q)
    assemble(u * v * dx, tensor=A00)
    assemble(p * v * dx, tensor=A01)
    assemble(u * q * dx, tensor=A10)

    AA = PETScNestMatrix([A00, A01, A10, None])

    # Create compatible RHS Vectors and insert into nest
    u = PETScVector()
    p = PETScVector()
    x = PETScVector()

    A00.init_vector(u, 1)
    A01.init_vector(p, 1)
    AA.init_vectors(x, [u, p])
Example #6
0
 def __init__(self, mesh, materials):
     """ init class always require mesh and materials to
     build the weak form """
     self.mesh = mesh
     self.materials = materials #FIXME throw error if not all domains are initilized
     self.eigenmode_guess = 1.0
     self.n_modes = 10 # number of modes to solve for      
     self.plot_eigenmodes = True
     self._A = PETScMatrix()
     self._B = PETScMatrix()	
     self.esolver = SLEPcEigenSolver(self._A, self._B)
Example #7
0
def cg1_cr_interpolation_matrix(mesh, constrained_domain=None):
    '''
    Compute matrix that allows fast interpolation of CG1 function to
    Couzeix-Raviart space.
    '''

    CG1 = VectorFunctionSpace(mesh,
                              'CG',
                              1,
                              constrained_domain=constrained_domain)
    CR = VectorFunctionSpace(mesh,
                             'CR',
                             1,
                             constrained_domain=constrained_domain)

    # Get the matrix with approximate sparsity as the interpolation matrix
    u = TrialFunction(CG1)
    v = TestFunction(CR)
    I = PETScMatrix()
    assemble(dot(u, v) * dx, tensor=I)

    # Fill the interpolation matrix
    d = mesh.geometry().dim()
    compiled_i_module.compute_cg1_cr_interpolation_matrix(I, d)

    return I
Example #8
0
def block_mat_to_petsc(bmat):
    '''Block mat to PETScMatrix via assembly'''

    # This is beautiful but slow as hell :)
    def iter_rows(matrix):
        for i in range(matrix.size(0)):
            yield matrix.getrow(i)

    row_sizes, col_sizes = get_sizes(bmat)
    row_offsets = np.cumsum([0] + list(row_sizes))
    col_offsets = np.cumsum([0] + list(col_sizes))

    with petsc_serial_matrix(row_offsets[-1], col_offsets[-1]) as mat:
        row = 0
        for row_blocks in bmat.blocks:
            # Zip the row iterators of the matrices together
            for indices_values in itertools.izip(*map(iter_rows, row_blocks)):
                indices, values = zip(*indices_values)

                indices = [
                    list(index + offset)
                    for index, offset in zip(indices, col_offsets)
                ]
                indices = sum(indices, [])

                row_values = np.hstack(values)

                mat.setValues([row], indices, row_values,
                              PETSc.InsertMode.INSERT_VALUES)

                row += 1
    return PETScMatrix(mat)
Example #9
0
def collapse(x):
    """Compute an explicit matrix representation of an operator. For example,
    given a block_ mul object M=A*B, collapse(M) performs the actual matrix
    multiplication.
    """
    # Since _collapse works recursively, this method is a user-visible wrapper
    # to print timing, and to check input/output arguments.
    from time import time
    from dolfin import PETScMatrix, info, warning
    T = time()
    res = _collapse(x)
    if getattr(res, 'transposed', False):
        # transposed matrices will normally be converted to a non-transposed
        # one by matrix multiplication or addition, but if the transpose is the
        # outermost operation then this doesn't work.
        res.M.transpose()
    info('computed explicit matrix representation %s in %.2f s' %
         (str(res), time() - T))

    result = PETScMatrix(res.M)

    # Sanity check. Cannot trust EpetraExt.Multiply always, it seems.
    from block import block_vec
    v = x.create_vec()
    block_vec([v]).randomize()
    xv = x * v
    err = (xv - result * v).norm('l2') / (xv).norm('l2')
    if (err > 1e-3):
        raise RuntimeError(
            'collapse computed wrong result; ||(a-a\')x||/||ax|| = %g' % err)

    return result
Example #10
0
def project(expr, space):
    u, v = TrialFunction(space), TestFunction(space)
    a = inner(u, v)*dx
    L = inner(expr, v)*dx
    A, b = PETScMatrix(), PETScVector()
    assemble_system(a, L, A_tensor=A, b_tensor=b)

    uh = Function(space)
    x = uh.vector()
    solve(A, x, b, 'lu')

    lmax = SLEPcEigenSolver(A)
    lmax.parameters["spectrum"] = "largest magnitude"
    lmax.parameters["problem_type"] = "hermitian"
    lmax.solve(2)
    lmax = max([lmax.get_eigenpair(i)[0] for i in range(lmax.get_number_converged())])

    lmin = SLEPcEigenSolver(A)
    lmin.parameters["spectrum"] = "smallest magnitude"
    lmin.parameters["problem_type"] = "hermitian"
    lmin.solve(2)
    lmin = max([lmin.get_eigenpair(i)[0] for i in range(lmin.get_number_converged())])

    print space.dim(), 'Cond number', lmax/lmin



    
    return uh
Example #11
0
def diagonal_matrix(size, A=1):
    '''Dolfin A*I serial only'''
    d = PETSc.Vec().createWithArray(A*np.ones(size))
    I = PETSc.Mat().createAIJ(size=size, nnz=1)
    I.setDiagonal(d)

    return PETScMatrix(I)
Example #12
0
    def get_work_dolfin_mat(self,
                            key,
                            comm,
                            can_be_destroyed=None,
                            can_be_shared=None):
        """Get working DOLFIN matrix by key. ``can_be_destroyed=True`` tells
        that it is probably favourable to not store the matrix unless it is
        shared as it will not be used ever again, ``None`` means that it can
        be destroyed but it is not probably favourable and ``False`` forbids
        the destruction. ``can_be_shared`` tells if a work matrix can be the
        same with work matrices for other keys."""
        # TODO: Add mechanism for sharing DOLFIN mats
        # NOTE: Maybe we don't really need sharing. If only persistent matrix
        #       is convection then there is nothing to be shared.

        # Check if requested matrix is in scratch
        dolfin_mat = self.scratch.get(key, None)

        # Allocate new matrix otherwise
        if dolfin_mat is None:

            if isinstance(comm, PETSc.Comm):
                comm = comm.tompi4py()

            dolfin_mat = PETScMatrix(comm)

        # Store or pop the matrix as requested
        if can_be_destroyed in [False, None]:
            self.scratch[key] = dolfin_mat
        else:
            assert can_be_destroyed is True
            self.scratch.pop(key, None)

        return dolfin_mat
Example #13
0
def injection_matrix(Vc, Vf, fine_mesh, data):
    '''Injection mapping from Vc to Vf'''
    mesh_c = Vc.mesh()
    assert fine_mesh.id() == Vf.mesh().id()
    mesh_f = Vf.mesh()

    if data['not_nested_method'] == 'interpolate':
        return df.PETScDMCollection.create_transfer_matrix(Vc, Vf)
    elif data['not_nested_method'] == 'project':
        raise ValueError('Missing projection')

    # Fallback to our interpolate with lookup, which, however is slower
    # to `create_transfer_matrix`

    tdim = mesh_f.topology().dim()
    # Refine was used to create it
    keys, fine_to_coarse = list(
        zip(*list(fine_mesh.parent_entity_map[mesh_c.id()][tdim].items())))
    fine_to_coarse = np.array(fine_to_coarse, dtype='uintp')
    fine_to_coarse[np.argsort(keys)] = fine_to_coarse

    # The idea is to evaluate Vf's degrees of freedom at basis functions of Vc
    fdmap = Vf.dofmap()
    Vf_dof = DegreeOfFreedom(Vf)

    cdmap = Vc.dofmap()
    Vc_basis_f = FEBasisFunction(Vc)

    # Column values
    visited_rows = [False] * Vf.dim()
    row_values = np.zeros(Vc_basis_f.elm.space_dimension(), dtype='double')

    with petsc_serial_matrix(Vf, Vc) as mat:

        for f_cell, c_cell in enumerate(fine_to_coarse):

            Vc_basis_f.cell = c_cell
            # These are the colums
            coarse_dofs = cdmap.cell_dofs(c_cell)

            Vf_dof.cell = f_cell

            fine_dofs = fdmap.cell_dofs(f_cell)

            for local, dof in enumerate(fine_dofs):
                if visited_rows[dof]:
                    continue
                else:
                    visited_rows[dof] = True

                Vf_dof.dof = local
                # Evaluete coarse basis foos here
                for local_c, dof_c in enumerate(coarse_dofs):
                    Vc_basis_f.dof = local_c
                    row_values[local_c] = Vf_dof.eval(Vc_basis_f)
                # Insert
                mat.setValues([dof], coarse_dofs, row_values,
                              PETSc.InsertMode.INSERT_VALUES)

    return PETScMatrix(mat)
Example #14
0
def trace_mat(V, TV, trace_mesh, data):
    '''
    A mapping for computing traces of function in V in TV. If f in V 
    then g in TV has coefficients equal to dofs_{TV}(trace V). Trace is 
    understood as D -> D-1.
    '''
    # Compatibility of spaces
    assert V.dolfin_element().value_rank() == TV.dolfin_element().value_rank()
    assert V.ufl_element().value_shape() == TV.ufl_element().value_shape()
    assert trace_cell(V) == TV.mesh().ufl_cell()
    assert V.mesh().geometry().dim() == TV.mesh().geometry().dim()

    # FIXME: trace element checking
    if trace_mesh is not None:
        assert trace_mesh.id() == TV.mesh().id()

    restriction = data['restriction']
    normal = data['normal']
    tag_data = data['tag_data']
    # Restriction is defined using the normal
    if restriction: assert normal is not None, 'R is %s' % restriction

    # Typically with CG spaces - any parent cell can set the valeus
    if not restriction:
        Tmat = trace_mat_no_restrict(V, TV, trace_mesh, tag_data=tag_data)
    else:
        if restriction in ('+', '-'):
            Tmat = trace_mat_one_restrict(V, TV, restriction, normal,
                                          trace_mesh, tag_data)
        else:
            assert restriction in ('avg', 'jump')
            Tmat = trace_mat_two_restrict(V, TV, restriction, normal,
                                          trace_mesh, tag_data)
    return PETScMatrix(Tmat)
Example #15
0
 def assemble_stiffness(self, mesh):
     V = FunctionSpace(mesh, "Lagrange", self.p)
     u = TrialFunction(V)
     v = TestFunction(V)
     k = inner(grad(u), grad(v)) * dx
     K = PETScMatrix()
     assemble(k, tensor=K)
     return K, V
Example #16
0
 def assemble_mass(self, mesh):
     V = FunctionSpace(mesh, "Lagrange", self.p)
     u = TrialFunction(V)
     v = TestFunction(V)
     m = u * v * dx
     M = PETScMatrix()
     assemble(m, tensor=M)
     return M
Example #17
0
def numpy_to_petsc(mat):
    '''Build PETScMatrix with array structure'''
    # Dense array to matrix
    if isinstance(mat, np.ndarray):
        return numpy_to_petsc(csr_matrix(mat))
    # Sparse
    A = PETSc.Mat().createAIJ(size=mat.shape,
                              csr=(mat.indptr, mat.indices, mat.data))
    return PETScMatrix(A)
Example #18
0
def transpose_matrix(A):
    '''Create a transpose of PETScMatrix/PETSc.Mat'''
    if isinstance(A, PETSc.Mat):
        At = PETSc.Mat()  # Alloc
        A.transpose(At)  # Transpose to At
        return At

    At = transpose_matrix(as_backend_type(A).mat())
    return PETScMatrix(At)
Example #19
0
    def _condense_matrix(self, mat):
        mat = as_backend_type(mat)

        petsc_version = PETSc.Sys().getVersionInfo()
        if petsc_version["major"] == 3 and petsc_version["minor"] <= 7:
            condensed_mat = mat.mat().getSubMatrix(self._is, self._is)
        else:
            condensed_mat = mat.mat().createSubMatrix(self._is, self._is)

        return mat, PETScMatrix(condensed_mat)
Example #20
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))
Example #21
0
def diagonal_matrix(size, A):
    '''Dolfin A*I serial only'''
    if isinstance(A, (int, float)):
        d = PETSc.Vec().createWithArray(A*np.ones(size))
    else:
        d = as_backend_type(A).vec()
    I = PETSc.Mat().createAIJ(size=size, nnz=1)
    I.setDiagonal(d)
    I.assemble()

    return PETScMatrix(I)
Example #22
0
def collapse_tr(bmat):
    '''to Transpose'''
    # Base
    A = bmat.A
    if is_petsc_mat(A):
        A_ = as_petsc(A)
        C_ = PETSc.Mat()
        A_.transpose(C_)
        return PETScMatrix(C_)
    # Recurse
    return collapse_tr(collapse(bmat))
Example #23
0
def zero_matrix(nrows, ncols):
    '''Zero matrix'''
    mat = csr_matrix((np.zeros(nrows, dtype=float),  # Data
                      # Rows, cols = so first col in each row is 0
                      (np.arange(nrows), np.zeros(nrows, dtype=int))),  
                     shape=(nrows, ncols))

    A = PETSc.Mat().createAIJ(size=[[nrows, nrows], [ncols, ncols]],
                              csr=(mat.indptr, mat.indices, mat.data))
    A.assemble()

    return PETScMatrix(A)
Example #24
0
def restriction_mat(V, TV, rmesh, data):
    '''
    A mapping for computing restriction of function in V in TV. If f in V 
    then g in TV has coefficients equal to dofs_{TV}(trace V).

    The TV space is assumed to be setup on subdmoain of V mesh.
    '''
    # Compatibility of spaces
    assert V.ufl_element() == TV.ufl_element()
    # Check that rmesh came from OverlapMesh
    assert V.mesh().id() in rmesh.parent_entity_map

    return PETScMatrix(restriction_matrix(V, TV, rmesh))
Example #25
0
def test_lu_cholesky():
    """Test that PETScLUSolver selects LU or Cholesky solver based on
    symmetry of matrix operator.

    """

    from petsc4py import PETSc

    mesh = UnitSquareMesh(mpi_comm_world(), 12, 12)
    V = FunctionSpace(mesh, "Lagrange", 1)
    u, v = TrialFunction(V), TestFunction(V)
    A = PETScMatrix(mesh.mpi_comm())
    assemble(Constant(1.0)*u*v*dx, tensor=A)

    # Check that solver type is LU
    solver = PETScLUSolver(mesh.mpi_comm(), A, "petsc")
    pc_type = solver.ksp().getPC().getType()
    assert pc_type == "lu"

    # Set symmetry flag
    A.mat().setOption(PETSc.Mat.Option.SYMMETRIC, True)

    # Check symmetry flags
    symm = A.mat().isSymmetricKnown()
    assert symm[0] == True
    assert symm[1] == True

    # Check that solver type is Cholesky since matrix has now been
    # marked as symmetric
    solver = PETScLUSolver(mesh.mpi_comm(), A, "petsc")
    pc_type = solver.ksp().getPC().getType()
    assert pc_type == "cholesky"

    # Re-assemble, which resets symmetry flag
    assemble(Constant(1.0)*u*v*dx, tensor=A)
    solver = PETScLUSolver(mesh.mpi_comm(), A, "petsc")
    pc_type = solver.ksp().getPC().getType()
    assert pc_type == "lu"
Example #26
0
def test_lu_cholesky():
    """Test that PETScLUSolver selects LU or Cholesky solver based on
    symmetry of matrix operator.

    """

    from petsc4py import PETSc

    mesh = UnitSquareMesh(MPI.comm_world, 12, 12)
    V = FunctionSpace(mesh, "Lagrange", 1)
    u, v = TrialFunction(V), TestFunction(V)
    A = PETScMatrix(mesh.mpi_comm())
    assemble(Constant(1.0)*u*v*dx, tensor=A)

    # Check that solver type is LU
    solver = PETScLUSolver(mesh.mpi_comm(), A, "petsc")
    pc_type = solver.ksp().getPC().getType()
    assert pc_type == "lu"

    # Set symmetry flag
    A.mat().setOption(PETSc.Mat.Option.SYMMETRIC, True)

    # Check symmetry flags
    symm = A.mat().isSymmetricKnown()
    assert symm[0] == True
    assert symm[1] == True

    # Check that solver type is Cholesky since matrix has now been
    # marked as symmetric
    solver = PETScLUSolver(mesh.mpi_comm(), A, "petsc")
    pc_type = solver.ksp().getPC().getType()
    assert pc_type == "cholesky"

    # Re-assemble, which resets symmetry flag
    assemble(Constant(1.0)*u*v*dx, tensor=A)
    solver = PETScLUSolver(mesh.mpi_comm(), A, "petsc")
    pc_type = solver.ksp().getPC().getType()
    assert pc_type == "lu"
Example #27
0
def test_petsc4py_matrix(pushpop_parameters):
    "Test PETScMatrix <-> petsc4py.PETSc.Mat conversions"
    parameters["linear_algebra_backend"] = "PETSc"

    # Assemble a test matrix
    mesh = UnitSquareMesh(4, 4)
    V = FunctionSpace(mesh, "Lagrange", 1)
    u, v = TrialFunction(V), TestFunction(V)
    a = u * v * dx
    A1 = assemble(a)

    # Test conversion dolfin.PETScMatrix -> petsc4py.PETSc.Mat
    A1 = as_backend_type(A1)
    M1 = A1.mat()

    # Copy and scale matrix with petsc4py
    M2 = M1.copy()
    M2.scale(2.0)

    # Test conversion petsc4py.PETSc.Mat  -> PETScMatrix
    A2 = PETScMatrix(M2)

    assert (A1.array() * 2.0 == A2.array()).all()
Example #28
0
def test_petsc4py_matrix(pushpop_parameters):
    "Test PETScMatrix <-> petsc4py.PETSc.Mat conversions"
    parameters["linear_algebra_backend"] = "PETSc"

    # Assemble a test matrix
    mesh = UnitSquareMesh(4, 4)
    V = FunctionSpace(mesh, "Lagrange", 1)
    u, v = TrialFunction(V), TestFunction(V)
    a = u*v*dx
    A1 = assemble(a)

    # Test conversion dolfin.PETScMatrix -> petsc4py.PETSc.Mat
    A1 = as_backend_type(A1)
    M1 = A1.mat()

    # Copy and scale matrix with petsc4py
    M2 = M1.copy()
    M2.scale(2.0)

    # Test conversion petsc4py.PETSc.Mat  -> PETScMatrix
    A2 = PETScMatrix(M2)

    assert (A1.array()*2.0 == A2.array()).all()
Example #29
0
def collapse_sub(bmat):
    '''A - B to single matrix'''
    A, B = bmat.A, bmat.B
    # Base case
    if is_petsc_mat(A) and is_petsc_mat(B):
        A_ = as_petsc(A)
        B_ = as_petsc(B)
        assert A_.size == B_.size
        C_ = A_.copy()
        # C = A - B
        C_.axpy(-1., B_, PETSc.Mat.Structure.DIFFERENT)
        return PETScMatrix(C_)
    # Recurse
    return collapse_sub(collapse(A) - collapse(B))
Example #30
0
 def assemble_lui_stiffness(self, g, f, mesh, robin_boundary):
     V = FunctionSpace(mesh, "Lagrange", self.p)
     u = TrialFunction(V)
     v = TestFunction(V)
     n = FacetNormal(mesh)
     robin = MeshFunction('size_t', mesh, mesh.topology().dim() - 1)
     robin_boundary.mark(robin, 1)
     ds = Measure('ds', subdomain_data=robin)
     a = inner(grad(u), grad(v)) * dx
     b = (1 - g) * (inner(grad(u), n)) * v * ds(1)
     c = f * u * v * ds(1)
     k = lhs(a + b - c)
     K = PETScMatrix()
     assemble(k, tensor=K)
     return K, V
Example #31
0
def row_matrix(rows):
    '''Short and fat matrix'''
    ncols, = set(row.size() for row in rows)
    nrows = len(rows)

    indptr = np.cumsum(np.array([0]+[ncols]*nrows))
    indices = np.tile(np.arange(ncols), nrows)
    data = np.hstack([row.get_local() for row in rows])

    mat = csr_matrix((data, indices, indptr), shape=(nrows, ncols))
    
    A = PETSc.Mat().createAIJ(size=[[nrows, nrows], [ncols, ncols]],
                              csr=(mat.indptr, mat.indices, mat.data))
    A.assemble()

    return PETScMatrix(A)
Example #32
0
def numpy_to_petsc(mat):
    '''Build PETScMatrix with array structure'''
    # Dense array to matrix
    if isinstance(mat, np.ndarray):
        if mat.ndim == 1:
            vec = PETSc.Vec().createWithArray(mat)
            vec.assemble()
            return PETScVector(vec)

        return numpy_to_petsc(csr_matrix(mat))
    # Sparse
    A = PETSc.Mat().createAIJ(comm=COMM,
                              size=mat.shape,
                              csr=(mat.indptr, mat.indices, mat.data))
    A.assemble()
    return PETScMatrix(A)