Esempio n. 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)
Esempio n. 2
0
    def J(self, x: PETSc.Vec, A: PETSc.Mat):
        """Assemble the Jacobian matrix.

        Args:
            x: The vector containing the latest solution

        """
        A.zeroEntries()
        assemble_matrix(A, self._a, self.bcs)
        A.assemble()
Esempio n. 3
0
    def J(self, snes, x: PETSc.Vec, A: PETSc.Mat, P: PETSc.Mat):
        """Assemble the Jacobian matrix.

        Parameters
        ==========
        x: Vector containing the latest solution.
        A: Matrix to assemble the Jacobian into.
        """
        A.zeroEntries()
        assemble_matrix(A, self.J_form, self.bcs)
        A.assemble()
Esempio n. 4
0
 def J(self, x: PETSc.Vec, A: PETSc.Mat):
     """Assemble the Jacobian matrix.
     Parameters
     ----------
     x
         The vector containing the latest solution
     A
         The matrix to assemble the Jacobian into
     """
     A.zeroEntries()
     assemble_matrix(A, self._a, self.bcs)
     A.assemble()
Esempio n. 5
0
    def restrict_matrix(self, A: PETSc.Mat):
        # Fetching IS only for owned dofs
        # Ghost dofs would get the same global index which would result in
        # duplicate global indices in global IS
        local_isrow = PETSc.IS(self.comm).createGeneral(
            self.bglobal_dofs_mat_stacked)
        global_isrow = A.getLGMap()[0].applyIS(local_isrow)

        subA = A.createSubMatrix(isrow=global_isrow, iscol=global_isrow)
        subA.assemble()

        return subA
Esempio n. 6
0
def _(A: PETSc.Mat,
      a: typing.List[typing.List[typing.Union[Form, cpp.fem.Form]]],
      bcs: typing.List[DirichletBC] = [],
      diagonal: float = 1.0) -> PETSc.Mat:
    """Assemble bilinear forms into matrix"""
    _a = _create_cpp_form(a)
    V = _extract_function_spaces(_a)
    is_rows = cpp.la.create_petsc_index_sets([(Vsub.dofmap.index_map, Vsub.dofmap.index_map_bs) for Vsub in V[0]])
    is_cols = cpp.la.create_petsc_index_sets([(Vsub.dofmap.index_map, Vsub.dofmap.index_map_bs) for Vsub in V[1]])

    # Assemble form
    for i, a_row in enumerate(_a):
        for j, a_sub in enumerate(a_row):
            if a_sub is not None:
                Asub = A.getLocalSubMatrix(is_rows[i], is_cols[j])
                cpp.fem.assemble_matrix_petsc_unrolled(Asub, a_sub, bcs)
                A.restoreLocalSubMatrix(is_rows[i], is_cols[j], Asub)

    # Flush to enable switch from add to set in the matrix
    A.assemble(PETSc.Mat.AssemblyType.FLUSH)

    # Set diagonal
    for i, a_row in enumerate(_a):
        for j, a_sub in enumerate(a_row):
            if a_sub is not None:
                Asub = A.getLocalSubMatrix(is_rows[i], is_cols[j])
                if a_sub.function_spaces[0].id == a_sub.function_spaces[1].id:
                    cpp.fem.insert_diagonal(Asub, a_sub.function_spaces[0], bcs, diagonal)
                A.restoreLocalSubMatrix(is_rows[i], is_cols[j], Asub)

    return A
Esempio n. 7
0
def _(A: PETSc.Mat,
      a: typing.Union[Form, cpp.fem.Form],
      bcs: typing.List[DirichletBC] = [],
      diagonal: float = 1.0) -> PETSc.Mat:
    """Assemble bilinear form into a matrix. The returned matrix is not
    finalised, i.e. ghost values are not accumulated.

    """
    _a = _create_cpp_form(a)
    cpp.fem.assemble_matrix_petsc(A, _a, bcs)
    if _a.function_spaces[0].id == _a.function_spaces[1].id:
        A.assemblyBegin(PETSc.Mat.AssemblyType.FLUSH)
        A.assemblyEnd(PETSc.Mat.AssemblyType.FLUSH)
        cpp.fem.insert_diagonal(A, _a.function_spaces[0], bcs, diagonal)
    return A
Esempio n. 8
0
def assemble_matrix_nest(
        A: _PETSc.Mat,
        a: Sequence[Sequence[_fem.FormMetaClass]],
        constraints: Sequence[MultiPointConstraint],
        bcs: Sequence[_fem.DirichletBCMetaClass] = [],
        diagval: _PETSc.ScalarType = 1):
    """
    Assemble a compiled DOLFINx bilinear form into a PETSc matrix of type
    "nest" with corresponding multi point constraints and Dirichlet boundary
    conditions.

    Parameters
    ----------
    a
        The compiled bilinear variational form provided in a rank 2 list
    constraints
        An ordered list of multi point constraints
    bcs
        Sequence of Dirichlet boundary conditions
    diagval
        Value to set on the diagonal of the matrix (Default 1)
    A
        PETSc matrix to assemble into
    """
    for i, a_row in enumerate(a):
        for j, a_block in enumerate(a_row):
            if a_block is not None:
                Asub = A.getNestSubMatrix(i, j)
                assemble_matrix(
                    a_block, (constraints[i], constraints[j]),
                    bcs=bcs, diagval=diagval, A=Asub)
Esempio n. 9
0
def _(A: PETSc.Mat,
      a: typing.List[typing.List[typing.Union[Form, cpp.fem.Form]]],
      bcs: typing.List[DirichletBC] = [],
      diagonal: float = 1.0) -> PETSc.Mat:
    """Assemble bilinear forms into matrix"""
    _a = _create_cpp_form(a)
    V = _extract_function_spaces(_a)
    is_rows = cpp.la.create_petsc_index_sets([(Vsub.dofmap.index_map, Vsub.dofmap.index_map_bs) for Vsub in V[0]])
    is_cols = cpp.la.create_petsc_index_sets([(Vsub.dofmap.index_map, Vsub.dofmap.index_map_bs) for Vsub in V[1]])
    for i, a_row in enumerate(_a):
        for j, a_sub in enumerate(a_row):
            if a_sub is not None:
                Asub = A.getLocalSubMatrix(is_rows[i], is_cols[j])
                assemble_matrix(Asub, a_sub, bcs, diagonal)
                A.restoreLocalSubMatrix(is_rows[i], is_cols[j], Asub)
    return A
Esempio n. 10
0
def gather_PETScMatrix(A: PETSc.Mat, root=0) -> scipy.sparse.csr_matrix:
    """
    Given a distributed PETSc matrix, gather in on process 'root' in
    a scipy CSR matrix
    """
    ai, aj, av = A.getValuesCSR()
    aj_all = MPI.COMM_WORLD.gather(aj, root=root)  # type: ignore
    av_all = MPI.COMM_WORLD.gather(av, root=root)  # type: ignore
    ai_all = MPI.COMM_WORLD.gather(ai, root=root)  # type: ignore
    if MPI.COMM_WORLD.rank == root:
        ai_cum = [0]
        for ai in ai_all:  # type: ignore
            offsets = ai[1:] + ai_cum[-1]
            ai_cum.extend(offsets)
        return scipy.sparse.csr_matrix(
            (np.hstack(av_all), np.hstack(aj_all), ai_cum),
            shape=A.getSize())  # type: ignore
Esempio n. 11
0
def _(A: PETSc.Mat,
      a: FormMetaClass,
      bcs: typing.List[DirichletBCMetaClass] = [],
      diagonal: float = 1.0,
      coeffs=Coefficients(None, None)) -> PETSc.Mat:
    """Assemble bilinear form into a matrix. The returned matrix is not
    finalised, i.e. ghost values are not accumulated.

    """
    c = (coeffs[0] if coeffs[0] is not None else pack_constants(a),
         coeffs[1] if coeffs[1] is not None else pack_coefficients(a))
    _cpp.fem.petsc.assemble_matrix(A, a, c[0], c[1], bcs)
    if a.function_spaces[0].id == a.function_spaces[1].id:
        A.assemblyBegin(PETSc.Mat.AssemblyType.FLUSH)
        A.assemblyEnd(PETSc.Mat.AssemblyType.FLUSH)
        _cpp.fem.petsc.insert_diagonal(A, a.function_spaces[0], bcs, diagonal)
    return A
Esempio n. 12
0
def _(A: PETSc.Mat,
      a: typing.Union[Form, cpp.fem.Form],
      bcs=[],
      diagonal: float = 1.0) -> PETSc.Mat:
    """Assemble bilinear form into an exiting matrix. The matrix is
    zeroed before assembly. Rows and columns of the matrix with
    Dirichlet boundary conditions zeroed, and ``scalar`` is placed on
    the diagonal for entries with a Dirichlet boundary condition.

    The matrix finalised, i.e. ghost values accumulated across MPI
    processes.

    """
    A.zeroEntries()
    a_cpp = _create_cpp_form(a)
    cpp.fem.assemble_matrix(A, a_cpp, bcs, diagonal)
    A.assemble()
    return A
Esempio n. 13
0
def matrix_split(Aww, badset):
    goodset = []
    nw = Aww.getSize()[0]
    for ki in range(nw):
        if ki not in badset:
            goodset.append(ki)
    goodset.sort()
    gtt = PETSc.IS()
    btt = PETSc.IS()
    gtt.createGeneral(goodset)
    btt.createGeneral(badset)
    A1 = Mat()
    A2 = Mat()
    Aww.createSubMatrix(gtt, gtt, A1)
    Aww.createSubMatrix(btt, btt, A2)
    eigfind.eigfind(A1)
    eigfind.eigfind(A2)
    return A1, A2
Esempio n. 14
0
def _(A: PETSc.Mat,
      a: typing.List[typing.List[typing.Union[Form, cpp.fem.Form]]],
      bcs: typing.List[DirichletBC] = [],
      diagonal: float = 1.0) -> PETSc.Mat:
    """Assemble bilinear forms into matrix"""
    _a = _create_cpp_form(a)
    for i, a_row in enumerate(_a):
        for j, a_block in enumerate(a_row):
            if a_block is not None:
                Asub = A.getNestSubMatrix(i, j)
                assemble_matrix(Asub, a_block, bcs)
    return A
Esempio n. 15
0
def assemble_matrix(form: _fem.FormMetaClass,
                    constraint: Union[MultiPointConstraint,
                                      Sequence[MultiPointConstraint]],
                    bcs: Sequence[_fem.DirichletBCMetaClass] = [],
                    diagval: _PETSc.ScalarType = 1,
                    A: _PETSc.Mat = None) -> _PETSc.Mat:
    """
    Assemble a compiled DOLFINx bilinear form into a PETSc matrix with corresponding multi point constraints
    and Dirichlet boundary conditions.

    Parameters
    ----------
    form
        The compiled bilinear variational form
    constraint
        The multi point constraint
    bcs
        Sequence of Dirichlet boundary conditions
    diagval
        Value to set on the diagonal of the matrix (Default 1)
    A
        PETSc matrix to assemble into (optional)

    Returns
    -------
    _PETSc.Mat
        The assembled bi-linear form
    """
    if not isinstance(constraint, Sequence):
        assert(form.function_spaces[0] == form.function_spaces[1])
        constraint = (constraint, constraint)

    # Generate matrix with MPC sparsity pattern
    if A is None:
        A = cpp.mpc.create_matrix(form, constraint[0]._cpp_object,
                                  constraint[1]._cpp_object)
    A.zeroEntries()

    # Assemble matrix in C++
    cpp.mpc.assemble_matrix(A, form, constraint[0]._cpp_object,
                            constraint[1]._cpp_object, bcs, diagval)

    # Add one on diagonal for Dirichlet boundary conditions
    if form.function_spaces[0] is form.function_spaces[1]:
        A.assemblyBegin(_PETSc.Mat.AssemblyType.FLUSH)
        A.assemblyEnd(_PETSc.Mat.AssemblyType.FLUSH)
        _cpp.fem.petsc.insert_diagonal(A, form.function_spaces[0], bcs, diagval)

    A.assemble()
    return A
Esempio n. 16
0
def petsc_to_local_CSR(A: PETSc.Mat, mpc: dolfinx_mpc.MultiPointConstraint):
    """
    Convert a PETSc matrix to a local CSR matrix (scipy) including ghost entries
    """
    global_indices = np.asarray(
        mpc.function_space.dofmap.index_map.global_indices(),
        dtype=PETSc.IntType)
    sort_index = np.argsort(global_indices)
    is_A = PETSc.IS().createGeneral(global_indices[sort_index])
    A_loc = A.createSubMatrices(is_A)[0]
    ai, aj, av = A_loc.getValuesCSR()
    A_csr = scipy.sparse.csr_matrix((av, aj, ai))
    return A_csr[global_indices[:, None], global_indices]
Esempio n. 17
0
    def assemble(self):
        """Ax=b    Assembles A and b using the matrices and RHS and indices
        stored in the file self.fmatrices.
        
        self.A, self.b and self.x then contain initialized petsc matricx and
        vectors.
        """
        l = Matrices(self.fmatrices)
        nn, ne, linear = l.loadsize()
        assert linear in [0, 1]
        if linear: dim = 4
        else: dim = 10
        self.nele = ne
        if self.verbose: pbar = MyBar("Global matrix and RHS: ")
        if self.verbose: pbar.init(ne - 1)

        IM = InsertMode.ADD_VALUES

        self.A = Mat()
        if linear: prealloc = 30
        else: prealloc = 100
        self.A.createSeqAIJ(nn, nz=prealloc)
        #        self.A.create()
        #        self.A.setSizes(nn)
        self.A.setFromOptions()
        #        self.A.option = Mat.Option.ROWS_SORTED
        #        self.A.option = Mat.Option.COLUMNS_SORTED
        #        self.A.option = Mat.Option.STRUCTURALLY_SYMMETRIC
        self.x, self.b = self.A.getVecs()
        self.b.zeroEntries()
        for i in range(ne):
            indices = l.loadindices(dim)
            Ae = l.loadmatrix(dim)
            Fe = l.loadvector(dim)
            self.A.setValues(indices, indices, Ae, IM)
            self.b.setValues(indices, Fe, IM)
            if self.verbose: pbar.update(i)
        self.A.assemble()
Esempio n. 18
0
def makecorrection(Ahlist, Bpet):
    nl = len(Ahlist) - 1
    Acorlist = [None] * nl
    for k in range(nl):
        Ah = Ahlist[k]
        btt = Bpet[k]
        Abad = Mat()
        Ah.createSubMatrix(btt, btt, Abad)
        Abad.assemblyBegin()
        Abad.assemblyEnd()
        Acorlist[k] = Abad.copy()

    return Acorlist
Esempio n. 19
0
def _(A: PETSc.Mat,
      a: typing.List[typing.List[FormMetaClass]],
      bcs: typing.List[DirichletBCMetaClass] = [],
      diagonal: float = 1.0,
      coeffs=Coefficients(None, None)) -> PETSc.Mat:
    """Assemble bilinear forms into matrix"""
    c = (coeffs[0] if coeffs[0] is not None else pack_constants(a),
         coeffs[1] if coeffs[1] is not None else pack_coefficients(a))
    for i, (a_row, const_row, coeff_row) in enumerate(zip(a, c[0], c[1])):
        for j, (a_block, const,
                coeff) in enumerate(zip(a_row, const_row, coeff_row)):
            if a_block is not None:
                Asub = A.getNestSubMatrix(i, j)
                assemble_matrix(Asub, a_block, bcs, diagonal, (const, coeff))
    return A
Esempio n. 20
0
def _(A: PETSc.Mat,
      a: typing.List[typing.List[FormMetaClass]],
      bcs: typing.List[DirichletBCMetaClass] = [],
      diagonal: float = 1.0,
      constants=None,
      coeffs=None) -> PETSc.Mat:
    """Assemble bilinear forms into matrix"""

    constants = [[form and _pack_constants(form) for form in forms]
                 for forms in a] if constants is None else constants
    coeffs = [[{} if form is None else _pack_coefficients(form)
               for form in forms] for forms in a] if coeffs is None else coeffs

    V = _extract_function_spaces(a)
    is_rows = _cpp.la.petsc.create_index_sets([
        (Vsub.dofmap.index_map, Vsub.dofmap.index_map_bs) for Vsub in V[0]
    ])
    is_cols = _cpp.la.petsc.create_index_sets([
        (Vsub.dofmap.index_map, Vsub.dofmap.index_map_bs) for Vsub in V[1]
    ])

    # Assemble form
    for i, a_row in enumerate(a):
        for j, a_sub in enumerate(a_row):
            if a_sub is not None:
                Asub = A.getLocalSubMatrix(is_rows[i], is_cols[j])
                _cpp.fem.petsc.assemble_matrix(Asub, a_sub, constants[i][j],
                                               coeffs[i][j], bcs, True)
                A.restoreLocalSubMatrix(is_rows[i], is_cols[j], Asub)

    # Flush to enable switch from add to set in the matrix
    A.assemble(PETSc.Mat.AssemblyType.FLUSH)

    # Set diagonal
    for i, a_row in enumerate(a):
        for j, a_sub in enumerate(a_row):
            if a_sub is not None:
                Asub = A.getLocalSubMatrix(is_rows[i], is_cols[j])
                if a_sub.function_spaces[0] is a_sub.function_spaces[1]:
                    _cpp.fem.petsc.insert_diagonal(Asub,
                                                   a_sub.function_spaces[0],
                                                   bcs, diagonal)
                A.restoreLocalSubMatrix(is_rows[i], is_cols[j], Asub)

    return A
Esempio n. 21
0
    def build_Wuu(self):
        Bm = as_backend_type(self.B).mat()
        BT = Bm.transpose(Mat())

        if self.point_variance:
            BtG_mat = BT.matMult(self.invG.mat())
            BtGB_mat = BtG_mat.matMult(Bm)
            BtGB = Matrix(PETScMatrix(BtGB_mat))
            Wuu = BtGB  #* du
            self.BtG = Matrix(PETScMatrix(BtG_mat))
        else:
            BtB_mat = BT.matMult(Bm)
            BtB = Matrix(PETScMatrix((1.0 / self.noise_variance) * BtB_mat))
            Wuu = BtB
            self.BtG = Matrix(PETScMatrix((1.0 / self.noise_variance) * BT))

        return Wuu
Esempio n. 22
0
def makecorrection(Ahlist, poorlist):

    Acorlist = [None] * (len(Ahlist) - 1)

    for k in range(len(Ahlist) - 1):
        Ah = Ahlist[k]
        badpet = PETSc.IS()
        badpet.createGeneral(poorlist[k])
        Abad = Mat()
        Ah.createSubMatrix(badpet, badpet, Abad)
        Abad.assemblyBegin()
        Abad.assemblyEnd()
        Acorlist[k] = Abad.copy()

    return Acorlist
Esempio n. 23
0
def _(A: PETSc.Mat,
      a: typing.List[typing.List[FormMetaClass]],
      bcs: typing.List[DirichletBCMetaClass] = [],
      diagonal: float = 1.0,
      constants=None,
      coeffs=None) -> PETSc.Mat:
    """Assemble bilinear forms into matrix"""
    constants = [[form and _pack_constants(form) for form in forms]
                 for forms in a] if constants is None else constants
    coeffs = [[{} if form is None else _pack_coefficients(form)
               for form in forms] for forms in a] if coeffs is None else coeffs
    for i, (a_row, const_row,
            coeff_row) in enumerate(zip(a, constants, coeffs)):
        for j, (a_block, const,
                coeff) in enumerate(zip(a_row, const_row, coeff_row)):
            if a_block is not None:
                Asub = A.getNestSubMatrix(i, j)
                assemble_matrix(Asub, a_block, bcs, diagonal, const, coeff)
    return A
Esempio n. 24
0
def poisson(da: PETSc.DM, spacing=None, a=0.0, b=1.0, A: PETSc.Mat = None,
            bcs=None) -> PETSc.Mat:
    """
    Return second order matrix for problem

    a I + b div grad

    Note
    ----
    this implementation is pretty slow. Can it be speeded up with cython somehow
    """
    if A is None:
        A = da.createMatrix()

    if spacing is None:
        spacing = [1.0] * da.dim

    if bcs is None:
        bcs = [0]*da.dim

    # use stencil to set entries
    row = PETSc.Mat.Stencil()
    col = PETSc.Mat.Stencil()


    if da.dim == 2:
        dx, dy = spacing

        hxy = dx/dy
        hyx = dy/dx
        ir = range(*da.ranges[0])
        jr = range(*da.ranges[1])

        dx, dy = spacing
        for i, j in product(ir, jr):
            row.index = (i,j)

            for index, value in [((i, j), a + b * (-2 * hyx - 2 *hxy)),
                                 ((i-1, j), b * hyx),
                                 ((i+1, j), b * hyx),
                                 ((i, j-1), b*hxy),
                                 ((i, j+1), b*hxy)]:
                col.index = index
                A.setValueStencil(row, col, value)

    A.assemblyBegin()
    A.assemblyEnd()

    return A
Esempio n. 25
0
    def assemble(self):
        """Ax=b    Assembles A and b using the matrices and RHS and indices
        stored in the file self.fmatrices.
        
        self.A, self.b and self.x then contain initialized petsc matricx and
        vectors.
        """
        l=Matrices(self.fmatrices)
        nn,ne,linear=l.loadsize()
        assert linear in [0,1]
        if linear: dim=4
        else: dim=10
        self.nele=ne
        if self.verbose: pbar=MyBar("Global matrix and RHS: ")
        if self.verbose: pbar.init(ne-1)

        IM=InsertMode.ADD_VALUES

        self.A=Mat()
        if linear: prealloc=30
        else: prealloc=100
        self.A.createSeqAIJ(nn,nz=prealloc)
#        self.A.create()
#        self.A.setSizes(nn)
        self.A.setFromOptions()
#        self.A.option = Mat.Option.ROWS_SORTED
#        self.A.option = Mat.Option.COLUMNS_SORTED
#        self.A.option = Mat.Option.STRUCTURALLY_SYMMETRIC
        self.x,self.b=self.A.getVecs()
        self.b.zeroEntries()
        for i in range(ne):
            indices=l.loadindices(dim)
            Ae=l.loadmatrix(dim)
            Fe=l.loadvector(dim)
            self.A.setValues(indices,indices,Ae,IM)
            self.b.setValues(indices,Fe,IM)
            if self.verbose: pbar.update(i)
        self.A.assemble()
Esempio n. 26
0
puse = []
#first one
#emax1=1.973297
#emax1=2.968916
#calc
# B1=[3241, 3748, 3751, 3496, 3753, 3242, 3243, 3244, 3245, 3246, 3500, 3501, 3502, 3503, 3504, 3505, 3506, 3763, 3764, 3511, 3762, 3761, 3509, 3253, 3508, 3255, 3752, 3497, 3498, 3247, 3239, 3757, 3758, 3251, 3252, 3507, 3059, 3318, 3510, 3765]
# B1.sort()
# matrix_split.matrix_split(Ahere,B1)
# quit()
emax1 = 1.973094
ptt = pnone[0].copy()
pnew = makenew(Ahere, ptt, emax1)
puse.append(pnew)

#second one
A2 = Mat()
Ahere.PtAP(pnew, A2)
#eigfind.eigfind(A2)
# B2 = [471, 408, 582, 583, 584, 585, 631, 455, 431, 498, 434, 500, 469, 470, 501, 499, 474, 539, 540, 541]
# B2.sort()
# matrix_split.matrix_split(A2,B2)
# quit()
ptt2 = pnone[1].copy()
#emax2=1.505117
#emax2=1.559350
# clac
emax2 = 1.504936
pnew2 = makenew(A2, ptt2, emax2)
puse.append(pnew2)

#third one
Esempio n. 27
0
L = f * v * dx + g * v * ds
A = PETScMatrix()
b = PETScVector()
assemble_system(a, L, bc, A_tensor=A, b_tensor=b)

A = A.mat()
b = b.vec()

# =========================================================================

# Construct the alist for systems on levels from fine to coarse
# construct the transfer operators first
ruse = [None] * (nl - 1)
Alist = [None] * (nl)

ruse[0] = Mat()
puse[0].transpose(ruse[0])
Alist[0] = A

for il in range(1, nl-1):
    ruse[il] = Mat()
    puse[il].transpose(ruse[il])
    Alist[il] = Mat()
    Alist[il - 1].PtAP(puse[il - 1], Alist[il])

# find the coarsest grid matrix
Alist[nl-1] = Mat()
Alist[nl-2].PtAP(puse[nl-2], Alist[nl-1])
# =========================================================

# Set initial guess
 def J(self, x: PETSc.Vec, A: PETSc.Mat):
     A.zeroEntries()
     dolfinx_mpc.assemble_matrix(self._a, self.mpc, bcs=self.bcs, A=A)
     A.assemble()
Esempio n. 29
0
        mat = pc.getMGInterpolation(ih)
        prouse.append(mat.copy())
        print(mat.size)

    pc.destroy()
    ksp.destroy()
    del ksp

    return nlevel, prouse


nl, prolongation = makepro(A, b)

restriction = [None] * (nl - 1)
Alist = [None] * nl
restriction[0] = Mat()
prolongation[0].transpose(restriction[0])
Alist[0] = Apt

for i_level in range(1, nl - 1):
    restriction[i_level] = Mat()
    prolongation[i_level].transpose(restriction[i_level])
    Alist[i_level] = Mat()
    Alist[i_level - 1].PtAP(prolongation[i_level - 1], Alist[i_level])

Bfinemore = [
    23041, 23042, 514, 31238, 31239, 31240, 31241, 41482, 31243, 36876, 36877,
    41484, 36879, 41485, 38434, 38435, 38436, 38437, 557, 26161, 26162, 26163,
    26164, 26165, 26166, 26167, 26168, 26169, 36930, 36931, 36933, 36934,
    36935, 36424, 36425, 36426, 36427, 36936, 36428, 36423, 36429, 36938, 593,
    594, 595, 592, 596, 598, 599, 597, 600, 36443, 36444, 603, 1119, 1120, 610,
Esempio n. 30
0
class System:

    def __init__(self,fmesh,fmatrices,fboundaries,verbose=True):
        self.fmesh=fmesh
        self.fmatrices=fmatrices
        self.fboundaries=fboundaries
        self.verbose=verbose

    def compute_element_matrices(self,bvalues,lam):
        """Calculates the element matrices and RHS and includes boundary
        conditions in them. The matrices and RHS together with global indices
        and are stored in self.fmatrices file.
        
        
        bvalues is a dict with boundary number and a double value
        example: bvalues={1:1.0, 2: 0.0}

        lam: double array of lambda for each element
        """
        if self.verbose: up=MyBar("Element matrices and RHS: ")
        else: up=None
        libmeshpy.mesh(self.fmesh,self.fmatrices,self.fboundaries,
                bvalues.values(),bvalues.keys(),lam,up)

    def assemble(self):
        """Ax=b    Assembles A and b using the matrices and RHS and indices
        stored in the file self.fmatrices.
        
        self.A, self.b and self.x then contain initialized petsc matricx and
        vectors.
        """
        l=Matrices(self.fmatrices)
        nn,ne,linear=l.loadsize()
        assert linear in [0,1]
        if linear: dim=4
        else: dim=10
        self.nele=ne
        if self.verbose: pbar=MyBar("Global matrix and RHS: ")
        if self.verbose: pbar.init(ne-1)

        IM=InsertMode.ADD_VALUES

        self.A=Mat()
        if linear: prealloc=30
        else: prealloc=100
        self.A.createSeqAIJ(nn,nz=prealloc)
#        self.A.create()
#        self.A.setSizes(nn)
        self.A.setFromOptions()
#        self.A.option = Mat.Option.ROWS_SORTED
#        self.A.option = Mat.Option.COLUMNS_SORTED
#        self.A.option = Mat.Option.STRUCTURALLY_SYMMETRIC
        self.x,self.b=self.A.getVecs()
        self.b.zeroEntries()
        for i in range(ne):
            indices=l.loadindices(dim)
            Ae=l.loadmatrix(dim)
            Fe=l.loadvector(dim)
            self.A.setValues(indices,indices,Ae,IM)
            self.b.setValues(indices,Fe,IM)
            if self.verbose: pbar.update(i)
        self.A.assemble()

    def solve(self,iterguess=23):
        """Solves the system Ax=b.

        A is stored in self.A
        b is stored in self.b
        x is stored in self.x 

        all three of them must be initialized petsc vectors (and a matrix) and
        the solution will be stored in self.x as a numpy array.

        The self.x is also returned from "solve", so that the user doesn't have
        to know about self.x.
        
        The iterguess is the guess for the number of iterations
        the solver is going to make. This is used in the progress bar. If
        it is overestimated, the progressbar will jump for example from 60% to
        100% at the end, if it is underestimated, the progressbar will stop
        at 99% (exactly at (iterguess-1)/iterguess * 100) but the solver will
        be still computing and the progressbar will be updated to 100% only
        when it returns."""
        if self.verbose: pbar=MyBar("Solving Ax=b: ")
        if self.verbose: pbar.init(iterguess)
        def upd(ksp,iter,rnorm):
            #print "iter:",iter,"norm:",rnorm
            if iter < iterguess: pbar.update(iter)
        ksp = KSP()
        ksp.create()
        ksp.setOperators(self.A,self.A,Mat.Structure.SAME_NONZERO_PATTERN)
        ksp.setFromOptions()
        if self.verbose: ksp.setMonitor(upd)
        ksp.solve(self.b,self.x)
        self.x=self.x.getArray()
        if self.verbose: pbar.update(iterguess)
        return self.x

    def gradient(self,x):
        """Computes a gradient of the scalar field defined on every
        node (numpy array x). 
        
        The gradient is computed on every element and the result is returned as
        a list of 3 numpy arrays (x,y,z) components."""
        gx = numpy.zeros(self.nele,'d')
        gy = numpy.zeros(self.nele,'d')
        gz = numpy.zeros(self.nele,'d')
        if self.verbose: up=MyBar("Gradient: ")
        else: up=None
        libmeshpy.grad(self.fmesh,x,gx,gy,gz,up)
        return gx,gy,gz

    def integ(self, grad, boundarynum):
        """Integrates the normal component of "grad" (list of 3 numpy arrays of
        floats for each element) over the boundary given by "boundarynum".

        We are integrating grad*n, where n is the normal, pointing always out
        of the element. boundarynum defines a set of elements and their faces,
        over which we are integrating and this defines the normal definitely.
        
        Returns a float (=the value of the surface integral)."""
        x,y,z=grad
        if self.verbose: up=MyBar("Integrating over surface %d: "%(boundarynum))
        else: up=None
        return libmeshpy.integ(self.fmesh,self.fboundaries,x,y,z,boundarynum,up)

    def save(self, fsol, x, g):
        "Saves x and g to a file fsol"
        import tables
        h5=tables.openFile(fsol,mode="w",title="Test")
        gsol=h5.createGroup(h5.root,"solver","Ax=b")
        h5.createArray(gsol,"x",x,"solution vector")
        h5.createArray(gsol,"grad",g,"gradient of the solution vector")
        h5.close()

    def load(self, fname):
        "Loads x and g from the file fname and returns (x,g)"
        import tables
        h5=tables.openFile(fname,mode="r")
        x=h5.root.solver.x.read()
        g=h5.root.solver.grad.read()
        h5.close()
        return (x,g)
Esempio n. 31
0
class System:
    def __init__(self, fmesh, fmatrices, fboundaries, verbose=True):
        self.fmesh = fmesh
        self.fmatrices = fmatrices
        self.fboundaries = fboundaries
        self.verbose = verbose

    def compute_element_matrices(self, bvalues, lam):
        """Calculates the element matrices and RHS and includes boundary
        conditions in them. The matrices and RHS together with global indices
        and are stored in self.fmatrices file.
        
        
        bvalues is a dict with boundary number and a double value
        example: bvalues={1:1.0, 2: 0.0}

        lam: double array of lambda for each element
        """
        if self.verbose: up = MyBar("Element matrices and RHS: ")
        else: up = None
        libmeshpy.mesh(self.fmesh, self.fmatrices, self.fboundaries,
                       bvalues.values(), bvalues.keys(), lam, up)

    def assemble(self):
        """Ax=b    Assembles A and b using the matrices and RHS and indices
        stored in the file self.fmatrices.
        
        self.A, self.b and self.x then contain initialized petsc matricx and
        vectors.
        """
        l = Matrices(self.fmatrices)
        nn, ne, linear = l.loadsize()
        assert linear in [0, 1]
        if linear: dim = 4
        else: dim = 10
        self.nele = ne
        if self.verbose: pbar = MyBar("Global matrix and RHS: ")
        if self.verbose: pbar.init(ne - 1)

        IM = InsertMode.ADD_VALUES

        self.A = Mat()
        if linear: prealloc = 30
        else: prealloc = 100
        self.A.createSeqAIJ(nn, nz=prealloc)
        #        self.A.create()
        #        self.A.setSizes(nn)
        self.A.setFromOptions()
        #        self.A.option = Mat.Option.ROWS_SORTED
        #        self.A.option = Mat.Option.COLUMNS_SORTED
        #        self.A.option = Mat.Option.STRUCTURALLY_SYMMETRIC
        self.x, self.b = self.A.getVecs()
        self.b.zeroEntries()
        for i in range(ne):
            indices = l.loadindices(dim)
            Ae = l.loadmatrix(dim)
            Fe = l.loadvector(dim)
            self.A.setValues(indices, indices, Ae, IM)
            self.b.setValues(indices, Fe, IM)
            if self.verbose: pbar.update(i)
        self.A.assemble()

    def solve(self, iterguess=23):
        """Solves the system Ax=b.

        A is stored in self.A
        b is stored in self.b
        x is stored in self.x 

        all three of them must be initialized petsc vectors (and a matrix) and
        the solution will be stored in self.x as a numpy array.

        The self.x is also returned from "solve", so that the user doesn't have
        to know about self.x.
        
        The iterguess is the guess for the number of iterations
        the solver is going to make. This is used in the progress bar. If
        it is overestimated, the progressbar will jump for example from 60% to
        100% at the end, if it is underestimated, the progressbar will stop
        at 99% (exactly at (iterguess-1)/iterguess * 100) but the solver will
        be still computing and the progressbar will be updated to 100% only
        when it returns."""
        if self.verbose: pbar = MyBar("Solving Ax=b: ")
        if self.verbose: pbar.init(iterguess)

        def upd(ksp, iter, rnorm):
            #print "iter:",iter,"norm:",rnorm
            if iter < iterguess: pbar.update(iter)

        ksp = KSP()
        ksp.create()
        ksp.setOperators(self.A, self.A, Mat.Structure.SAME_NONZERO_PATTERN)
        ksp.setFromOptions()
        if self.verbose: ksp.setMonitor(upd)
        ksp.solve(self.b, self.x)
        self.x = self.x.getArray()
        if self.verbose: pbar.update(iterguess)
        return self.x

    def gradient(self, x):
        """Computes a gradient of the scalar field defined on every
        node (numpy array x). 
        
        The gradient is computed on every element and the result is returned as
        a list of 3 numpy arrays (x,y,z) components."""
        gx = numpy.zeros(self.nele, 'd')
        gy = numpy.zeros(self.nele, 'd')
        gz = numpy.zeros(self.nele, 'd')
        if self.verbose: up = MyBar("Gradient: ")
        else: up = None
        libmeshpy.grad(self.fmesh, x, gx, gy, gz, up)
        return gx, gy, gz

    def integ(self, grad, boundarynum):
        """Integrates the normal component of "grad" (list of 3 numpy arrays of
        floats for each element) over the boundary given by "boundarynum".

        We are integrating grad*n, where n is the normal, pointing always out
        of the element. boundarynum defines a set of elements and their faces,
        over which we are integrating and this defines the normal definitely.
        
        Returns a float (=the value of the surface integral)."""
        x, y, z = grad
        if self.verbose:
            up = MyBar("Integrating over surface %d: " % (boundarynum))
        else:
            up = None
        return libmeshpy.integ(self.fmesh, self.fboundaries, x, y, z,
                               boundarynum, up)

    def save(self, fsol, x, g):
        "Saves x and g to a file fsol"
        import tables
        h5 = tables.openFile(fsol, mode="w", title="Test")
        gsol = h5.createGroup(h5.root, "solver", "Ax=b")
        h5.createArray(gsol, "x", x, "solution vector")
        h5.createArray(gsol, "grad", g, "gradient of the solution vector")
        h5.close()

    def load(self, fname):
        "Loads x and g from the file fname and returns (x,g)"
        import tables
        h5 = tables.openFile(fname, mode="r")
        x = h5.root.solver.x.read()
        g = h5.root.solver.grad.read()
        h5.close()
        return (x, g)
Esempio n. 32
0
def mg(Ah, bh, uh, prolongation, N_cycles, N_levels, ksptype, pctype):
    '''multigrid for N level mesh
    Ah is the matrix, bh is rhs on the finest grid,
    uh is the initial guess for finest grid
    prolongation is a list containing all of operators from fine-to-coarse
    N_cycles is number of cycles and N_levels is number of levels'''

    r0 = residual(Ah, bh, uh)

    # make a restriction list and gird operator list and rhs list
    # and initial guess list
    # initialize the first entity
    restriction = [None] * (N_levels - 1)
    Alist = [None] * N_levels
    blist = [None] * N_levels
    restriction[0] = Mat()
    prolongation[0].transpose(restriction[0])
    uhlist = [None] * N_levels
    Alist[0] = Ah
    blist[0] = bh
    uhlist[0] = uh

    # calculate the restriction, matrix, and initial guess lists
    # except coarsest grid, since transfer operator and initial guess
    # is not defined on that level
    for i_level in range(1, N_levels - 1):
        restriction[i_level] = Mat()
        prolongation[i_level].transpose(restriction[i_level])
        Alist[i_level] = Mat()
        Alist[i_level - 1].PtAP(prolongation[i_level - 1], Alist[i_level])
        uhlist[i_level] = restriction[i_level - 1] * uhlist[i_level - 1]

    # find the coarsest grid matrix
    Alist[N_levels - 1] = Mat()
    Alist[N_levels - 2].PtAP(prolongation[N_levels - 2], Alist[N_levels - 1])

    for num_cycle in range(N_cycles):

        # restriction to coarse grids
        for i in range(N_levels - 1):

            # apply smoother to every level except the coarsest level
            local_correction(Alist[i], blist[i], uhlist[i], Blist[i])
            smoother(Alist[i], blist[i], 1, uhlist[i], ksptype, pctype)
            local_correction(Alist[i], blist[i], uhlist[i], Blist[i])
            smoother(Alist[i], blist[i], 1, uhlist[i], ksptype, pctype)
            local_correction(Alist[i], blist[i], uhlist[i], Blist[i])

            # obtain the rhs for next level
            res = blist[i] - Alist[i] * uhlist[i]
            blist[i + 1] = restriction[i] * res

        # on the coarsest grid, apply direct lu
        uhlist[N_levels - 1] = direct(Alist[N_levels - 1], blist[N_levels - 1])

        # prolongation back to fine grids
        for j in range(N_levels - 2, -1, -1):

            uhlist[j] += prolongation[j] * uhlist[j + 1]
            local_correction(Alist[j], blist[j], uhlist[j], Blist[j])
            smoother(Alist[j], blist[j], 1, uhlist[j], ksptype, pctype)
            local_correction(Alist[j], blist[j], uhlist[j], Blist[j])
            smoother(Alist[j], blist[j], 1, uhlist[j], ksptype, pctype)
            local_correction(Alist[j], blist[j], uhlist[j], Blist[j])

        # calculate the relative residual
        res4 = residual(Ah, bh, uhlist[0]) / r0
        #print('relative residual after', num_cycle + 1, 'cycles is:', res4)
        print(res4)

    return uhlist[0]
Esempio n. 33
0
    ksp.destroy()
    del ksp

    return nlevel, prouse


# find the number of levels and prolongation list of AMG
nl, puse = makepro(A, b)
#eigfind.eigfind(Apt)
#quit()

#================================================================================

ruse = [None] * (nl - 1)
Ause = [None] * nl
ruse[0] = Mat()
puse[0].transpose(ruse[0])
Ause[0] = Apt

for il in range(1, nl - 1):
    ruse[il] = Mat()
    puse[il].transpose(ruse[il])
    Ause[il] = Mat()
    Ause[il - 1].PtAP(puse[il - 1], Ause[il])

# find the coarsest grid matrix
Ause[nl - 1] = Mat()
Ause[nl - 2].PtAP(puse[nl - 2], Ause[nl - 1])


#============================================================================
Esempio n. 34
0
U = np.loadtxt('SVD_basis')
U = U[:,0:DB]
U_transpose = U.conj().T
#load mass matrix and reduce it
 
rp = np.loadtxt('iam',int)
rp = rp.astype(petsc4py.PETSc.IntType)
ci = np.loadtxt('jam',int)
ci = ci.astype(petsc4py.PETSc.IntType)
nz = np.loadtxt('am')

nr = rp.shape[0] - 1
nc = nr

M = Mat().createAIJ(size=(nr,nc),csr=(rp,ci,nz))

M_intermediate = np.zeros((nr,DB),'d')

for i in range(0,nr):
    res = M.getRow(i)
    M_intermediate[i,:] = np.dot(res[1],U[res[0],:])

M_pod = np.dot(U_transpose, M_intermediate)
np.savetxt('M_pod', M_pod, delimiter=' ')

#load stiffness matrix and reduce it

rp = np.loadtxt('ias',int)
rp = rp.astype(petsc4py.PETSc.IntType)
ci = np.loadtxt('jas',int)