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
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
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
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)
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
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
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