Beispiel #1
0
    def __iadd__(self, other):
        if other != 0:
            if not other._getMatrix().Filled():
                other._getMatrix().FillComplete()

            # Depending on which one is more filled, pick the order of operations
            if self._getMatrix().Filled() and other._getMatrix().NumGlobalNonzeros() \
                                            > self._getMatrix().NumGlobalNonzeros():
                tempBandwidth = other._getMatrix().NumGlobalNonzeros() \
                                 /self._getMatrix().NumGlobalRows()+1

                tempMatrix = Epetra.CrsMatrix(Epetra.Copy, self.nonOverlappingMap, tempBandwidth)

                if EpetraExt.Add(other._getMatrix(), False, 1, tempMatrix, 1) != 0:
                    import warnings
                    warnings.warn("EpetraExt.Add returned error code in __iadd__, 1",
                                   UserWarning, stacklevel=2)

                if EpetraExt.Add(self._getMatrix(), False, 1, tempMatrix, 1) != 0:
                    import warnings
                    warnings.warn("EpetraExt.Add returned error code in __iadd__, 2",
                                   UserWarning, stacklevel=2)

                self.matrix = tempMatrix

            else:
                if EpetraExt.Add(other._getMatrix(), False,1,self._getMatrix(),1) != 0:
                    import warnings
                    warnings.warn("EpetraExt.Add returned error code in __iadd__",
                                   UserWarning, stacklevel=2)

        return self
Beispiel #2
0
    def get_negative_matrix(self, matrix, n):
        std_map = Epetra.Map(n, 0, self.comm)
        if matrix.Filled() == False:
            matrix.FillComplete()
        A = Epetra.CrsMatrix(Epetra.Copy, std_map, 3)

        EpetraExt.Add(matrix, False, -1.0, A, 1.0)

        return A
Beispiel #3
0
    def add(self, other, lscale=1.0, rscale=1.0):
        try:
            other = other.down_cast()
        except AttributeError:
            #raise TypeError("can't extract matrix data from type '%s'"%str(type(other)))
            pass

        if hasattr(other, 'mat'):
            from PyTrilinos import Epetra, EpetraExt
            C = Epetra.FECrsMatrix(Epetra.Copy, self.rowmap(), 100)
            assert (0 == EpetraExt.Add(self.M,      self.transposed,  lscale, C, 0.0))
            assert (0 == EpetraExt.Add(other.mat(), other.transposed, rscale, C, 1.0))
            C.FillComplete()
            C.OptimizeStorage()
            return matrix_op(C)
        else:
            lhs = self.matmat(lscale)
            D = Diag(lhs).add(other, rscale=rscale)
            lhs.M.ReplaceDiagonalValues(D.vec())
            return lhs
Beispiel #4
0
    def get_i_Jac(self, xVec):
        """
        Calculate total current and Jacobian

        Returns (iVec, Jac)::

            iVec = G xVec + i(xVec)
            Jac = G + (di/dx)(xVec)

        xVec: input vector of nodal voltages. 

        iVec: output vector of currents

        Jac: system Jacobian
        """
        # Copy xVec to pytrilinos vector
        self.xVec[:] = xVec
        # Erase arrays
        self.iVec.fill(0.)
        # Erase M and add linear contribution to iVec and M
        self.G.Multiply(False, self.xVec, self.iVec)
        # For now just re-create. Later this could somehow be
        # optimized
        self.Jacnz = [([], []) for i in xrange(self.ckt.nD_dimension)]
        # Erase Jac and add G in one step
        EpetraExt.Add(self.G, False, 1., self.Jac, 0.)

        # Nonlinear contribution
        for elem in self.ckt.nD_nlinElem:
            # first have to retrieve port voltages from xVec
            xin = np.zeros(len(elem.controlPorts))
            set_xin(xin, elem.nD_vpos, elem.nD_vneg, xVec)
            (outV, outJac) = elem.eval_and_deriv(xin)
            # Update iVec and Jacobian now. outV may have extra charge
            # elements but they are not used in the following
            set_i(self.iVec, elem.nD_cpos, elem.nD_cneg, outV)
            set_Jac(self.Jacnz, elem.nD_cpos, elem.nD_cneg, elem.nD_vpos,
                    elem.nD_vneg, outJac)

        # Insert actual elements in M
        for row, data in enumerate(self.Jacnz):
            self.Jac.SumIntoGlobalValues(row, *data)

        return (self.iVec, self.Jac)
Beispiel #5
0
def create_matrix(unique_map, edge_attributes, subnetworks=None, inter_processor_edges=None, inter_subgraph_edges=None, matformat="trilinos"):
    A = Epetra.CrsMatrix(Epetra.Copy, unique_map, 50)
    my_global_elements_set = set(unique_map.MyGlobalElements())

    row_lists = []
    col_lists = []
    val_lists = []

    if inter_processor_edges is not None:
        vertices_1 = inter_processor_edges['edgelist'][0]
        vertices_2 = inter_processor_edges['edgelist'][1]

        if len(vertices_1) > 0:
            assert set(vertices_1) <= my_global_elements_set, inter_processor_edges
            assert not set(vertices_2) <= my_global_elements_set, inter_processor_edges

            for attr in edge_attributes:
                row_lists.append(vertices_1)
                col_lists.append(vertices_2)
                val_lists.append(inter_processor_edges[attr])

    if inter_subgraph_edges is not None:
        vertices_1 = inter_subgraph_edges['edgelist'][0]
        vertices_2 = inter_subgraph_edges['edgelist'][1]

        assert set(vertices_1) <= my_global_elements_set, inter_subgraph_edges
        assert set(vertices_2) <= my_global_elements_set, inter_subgraph_edges

        for attr in edge_attributes:
            row_lists.append(vertices_1)
            col_lists.append(vertices_2)
            val_lists.append(inter_subgraph_edges[attr])
            row_lists.append(vertices_2)
            col_lists.append(vertices_1)
            val_lists.append(inter_subgraph_edges[attr])

    if subnetworks is not None:
        for i in subnetworks:
            vertices_1_local = subnetworks[i].edgelist[:, 0]
            vertices_2_local = subnetworks[i].edgelist[:, 1]
            vertices_1_global = subnetworks[i].pi_local_to_global[vertices_1_local]
            vertices_2_global = subnetworks[i].pi_local_to_global[vertices_2_local]

            assert set(vertices_1_global) <= my_global_elements_set
            assert set(vertices_2_global) <= my_global_elements_set

            cond = np.zeros(subnetworks[i].tubes.nr)
            for attr in edge_attributes:
                cond += getattr(subnetworks[i].tubes, attr)

            row_lists.append(vertices_1_global)
            col_lists.append(vertices_2_global)
            val_lists.append(cond)
            row_lists.append(vertices_2_global)
            col_lists.append(vertices_1_global)
            val_lists.append(cond)

    if matformat == "trilinos":
        for row, col, val in izip(row_lists, col_lists, val_lists):
            ierr = A.InsertGlobalValues(row, col, val)
            assert ierr == 0, ierr

        A.FillComplete()

        ones = Epetra.Vector(unique_map)
        ones[:] = 1.0

        x = Epetra.Vector(unique_map)
        A.Multiply(False, ones, x)

        D = Epetra.CrsMatrix(Epetra.Copy, unique_map, 50, True)

        row_inds = D.Map().MyGlobalElements()
        ierr = D.InsertGlobalValues(row_inds, row_inds, x)
        assert ierr == 0, ierr

        ierr = EpetraExt.Add(A, False, -1.0, D, 1.0)
        assert ierr == 0, ierr

        D.FillComplete()
        check = sum_of_columns(D)
        if check:
            error = np.max(np.abs(check[:]))
            assert error < 1.e-14, error

        return D

    if matformat == "scipy":
        N = unique_map.NumGlobalElements()
        row = np.concatenate(row_lists)
        col = np.concatenate(col_lists)
        val = np.concatenate(val_lists)
        A = coo_matrix((val, (row, col)), shape=(N, N))
        ones = np.ones(N)
        x = A*ones
        D = diags(x)
        A = D-A
        error = np.max(np.abs(A*ones))
        assert error < 1.e-14, error
        return A
Beispiel #6
0
def create_matrix_from_graph(unique_map, edge_attributes, graph, subnetworks=None, inter_processor_edges=None, inter_subgraph_edges=None):
    A = Epetra.CrsMatrix(Epetra.Copy, graph)
    A.PutScalar(0.0)
    my_global_elements_set = set(unique_map.MyGlobalElements())

    row_lists = []
    col_lists = []
    val_lists = []

    if inter_processor_edges is not None:
        vertices_1 = inter_processor_edges['edgelist'][0]
        vertices_2 = inter_processor_edges['edgelist'][1]

        if len(vertices_1) > 0:
            assert set(vertices_1) <= my_global_elements_set, inter_processor_edges
            assert not set(vertices_2) <= my_global_elements_set, inter_processor_edges

            for attr in edge_attributes:
                row_lists.append(vertices_1)
                col_lists.append(vertices_2)
                val_lists.append(inter_processor_edges[attr])

    if inter_subgraph_edges is not None:
        vertices_1 = inter_subgraph_edges['edgelist'][0]
        vertices_2 = inter_subgraph_edges['edgelist'][1]

        assert set(vertices_1) <= my_global_elements_set, inter_subgraph_edges
        assert set(vertices_2) <= my_global_elements_set, inter_subgraph_edges

        for attr in edge_attributes:
            row_lists.append(vertices_1)
            col_lists.append(vertices_2)
            val_lists.append(inter_subgraph_edges[attr])
            row_lists.append(vertices_2)
            col_lists.append(vertices_1)
            val_lists.append(inter_subgraph_edges[attr])

    if subnetworks is not None:
        for i in subnetworks:
            vertices_1_local = subnetworks[i].edgelist[:, 0]
            vertices_2_local = subnetworks[i].edgelist[:, 1]
            vertices_1_global = subnetworks[i].pi_local_to_global[vertices_1_local]
            vertices_2_global = subnetworks[i].pi_local_to_global[vertices_2_local]

            assert set(vertices_1_global) <= my_global_elements_set
            assert set(vertices_2_global) <= my_global_elements_set

            cond = np.zeros(subnetworks[i].tubes.nr)
            for attr in edge_attributes:
                cond += getattr(subnetworks[i].tubes, attr)

            row_lists.append(vertices_1_global)
            col_lists.append(vertices_2_global)
            val_lists.append(cond)
            row_lists.append(vertices_2_global)
            col_lists.append(vertices_1_global)
            val_lists.append(cond)

    row_lists = np.concatenate(row_lists).astype(np.int32)
    col_lists = np.concatenate(col_lists).astype(np.int32)
    val_lists = np.concatenate(val_lists)


    ierr = A.SumIntoGlobalValues(row_lists, col_lists, val_lists)
    assert ierr == 0, ierr

    A.FillComplete()

    ones = Epetra.Vector(unique_map)
    ones[:] = 1.0

    x = Epetra.Vector(unique_map)
    A.Multiply(False, ones, x)

    D = Epetra.CrsMatrix(Epetra.Copy, graph)
    D.PutScalar(0.0)

    row_inds = D.Map().MyGlobalElements()
    ierr = D.SumIntoGlobalValues(row_inds, row_inds, x)
    assert ierr == 0, ierr

    ierr = EpetraExt.Add(A, False, -1.0, D, 1.0)
    assert ierr == 0, ierr

    D.FillComplete()
    check = sum_of_columns(D)
    if check:
        error = np.max(np.abs(check[:]))
        assert error < 1.e-14, error

    return D
Beispiel #7
0
    def smooth_prolongation_operator(self,
                                     A,
                                     max_iter=1000,
                                     tol=1.e-2,
                                     verbose=False):
        """
        Parameters
        ----------
        A: Epetra matrix

        max_iter: integer
            Number of smoothing steps

        verbose: bool
            Flag to output convergence information

        Notes
        -----
        See  Algorithm 2 in Mandel et al 1999. However Jacobi iteration is used for smoothing as opposed to
        gradient descent.
        """

        support_matrix_copy = Epetra.CrsMatrix(self.N)
        tau = Epetra.Vector(A.RangeMap())
        J = DinvA(A)
        ierr = 0
        delta_P_temp = Epetra.CrsMatrix(Epetra.Copy, A.RangeMap(), 40)

        for iter_n in xrange(max_iter):
            sum_cols_P = sum_of_columns(self.P)
            assert np.allclose(sum_cols_P[:], 1.0)

            ierr += EpetraExt.Multiply(J, False, self.P, False, delta_P_temp)

            # Drop entries of delta_P_temp not matching the structure of delta_P
            self.delta_P.PutScalar(0.0)
            ierr += EpetraExt.Add(delta_P_temp, False, 1.0, self.delta_P,
                                  1.0)  # delta_P = N*(D^-1 AP)

            sum_cols_delta_P = sum_of_columns(self.delta_P)

            assert np.all(self.num_overlaps[:] >= 1)

            tau[:] = sum_cols_delta_P[:] / self.num_overlaps[:]
            support_matrix_copy.PutScalar(1.0)
            support_matrix_copy.LeftScale(tau)  # last term in Equation (19)

            ierr += EpetraExt.Add(support_matrix_copy, False, -1.0,
                                  self.delta_P, 1.0)  # delta_P = Z(N*D^-1AP)

            sum_cols_delta_P = sum_of_columns(self.delta_P)
            assert np.allclose(sum_cols_delta_P[:], 0.0)
            ierr += EpetraExt.Add(self.delta_P, False, -0.5, self.P, 1.0)

            error = self.delta_P.NormInf()
            if error < tol:
                break

        logger.debug(
            "Basis function error: %g. Number of iterations required: %d",
            error, iter_n)

        if verbose:
            print "Basis function error: %g. Number of iterations required: %d" % (
                error, iter_n)

        sum_cols_P = sum_of_columns(self.P)

        assert np.allclose(sum_cols_P[:], 1.0, atol=1.e-1000, rtol=1e-12)

        # Important numerical  step to ensure that mass is exactly conserved to machine zero
        """
        tau[:] = 1./sum_cols_P[:]
        self.P.LeftScale(tau)
        sum_cols_P = sum_of_columns(self.P)

        assert np.allclose(sum_cols_P[:], 1.0, atol=1.e-1000, rtol=1.e-15)
        """
        assert ierr == 0