def __init__(self, size, bandwidth=0, sizeHint=None, nonOverlappingMap=None, overlappingMap=None): """Creates a `_TrilinosMatrix`. :Parameters: - `size`: The size N for an N by N matrix. - `bandwidth`: The proposed band width of the matrix. - `sizeHint`: ??? - `map`: The Epetra `Map` for the rows that this processor holds """ if sizeHint is not None and bandwidth == 0: bandwidth = (sizeHint + size - 1) / (size or 1) else: bandwidth = bandwidth if nonOverlappingMap is None: comm = Epetra.PyComm() # Matrix building gets done on one processor - it gets the map for # all the rows if comm.MyPID() == 0: nonOverlappingMap = Epetra.Map(size, range(0, size), 0, comm) else: nonOverlappingMap = Epetra.Map(size, [], 0, comm) matrix = Epetra.CrsMatrix(Epetra.Copy, nonOverlappingMap, bandwidth*3/2) # Leave extra bandwidth, to handle multiple insertions into the # same spot. It's memory-inefficient, but it'll get cleaned up when # FillComplete is called, and according to the Trilinos devs the # performance boost will be worth it. _TrilinosMatrixBase.__init__(self, matrix=matrix, nonOverlappingMap=nonOverlappingMap, overlappingMap=overlappingMap, bandwidth=bandwidth)
def solve_linear_problem(self, A, b, x=None, its=1000, tolerance=1e-10): ''' resolve o problema Ax = b input: A: matriz quadrada esparsa do scipy b = termo fonte x: chute inicial its: numero maximo de iteracoes tolerance: tolerancia para o residuo output: res: informa se o residuo foi menor que a tolerancia x2: vetor resposta ''' comm = self._comm n = len(b) std_map = Epetra.Map(n, 0, comm) x2 = Epetra.Vector(std_map) if x: x2[:] = x[:] b2 = Epetra.Vector(std_map) b2[:] = b[:] A2 = Epetra.CrsMatrix(Epetra.Copy, std_map, 7) indices = sp.find(A) A2.InsertGlobalValues(indices[0], indices[1], indices[2]) irr = A2.FillComplete() linearProblem = Epetra.LinearProblem(A2, x2, b2) solver = AztecOO.AztecOO(linearProblem) solver.SetAztecOption(AztecOO.AZ_output, AztecOO.AZ_warnings) # solver.SetParameters(self._params) solver.Iterate(its, tolerance) x2 = np.array(x2) res = solver.ScaledResidual() < tolerance return x2
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 matrix_scipy_to_epetra(A_scipy, A_epetra=None): """ Converts scipy matrix to a local (non-distributed) epetra matrix. Parameters ---------- A_scipy: Scipy Matrix A_epetra: Epetra Matrix, optional An existing epetra matrix which has the same structure as the scipy matrix Returns ------- A_epetra: Epetra Matrix If an existing Epetra matrix is passed, the values are replaced """ comm = Epetra.MpiComm(MPI.COMM_SELF) map = Epetra.Map(A_scipy.shape[0], 0, comm) B = A_scipy.tocoo() if A_epetra is None: A_epetra = Epetra.CrsMatrix(Epetra.Copy, map, A_scipy.getnnz(axis=1).astype(np.int32), True) A_epetra.InsertGlobalValues(B.row, B.col, B.data) ierr = A_epetra.FillComplete() else: ierr = A_epetra.ReplaceMyValues(B.row, B.col, B.data) assert ierr == 0 return A_epetra
def _create_structure_matrix(row_map, my_supports, val=1.0): """ Creates N x M matrix where N is the number of vertices in the graph and M is the number of basis functions. This matrix encodes which basis function supports (which is identified by their column ids) a given vertex (which is identified by row id) belongs to. Note: one vertex may belong to multiple supports. """ range_map = row_map comm = range_map.Comm() domain_map = Epetra.Map(-1, my_supports.keys(), 0, comm) A = Epetra.CrsMatrix(Epetra.Copy, range_map, 30) for basis_id in my_supports: my_fine_cell_ids = my_supports[basis_id] size = len(my_fine_cell_ids) assert size > 0 ierr = A.InsertGlobalValues(my_fine_cell_ids, [int(basis_id)] * size, [val] * size) assert ierr == 0 A.FillComplete(domain_map, range_map) a = sum_of_columns(A) assert np.all(a[:] >= 1.0) return A
def _prolongation_operator_init(row_map, my_restriction_supports, my_basis_supports): """ Creates N x M matrix where N is the number of vertices in the graph and M is the number of basis functions """ range_map = row_map comm = range_map.Comm() domain_map = Epetra.Map(-1, my_basis_supports.keys(), 0, comm) P = Epetra.CrsMatrix(Epetra.Copy, range_map, 30) for basis_id in my_basis_supports: my_fine_cell_ids = my_basis_supports[basis_id] size = len(my_fine_cell_ids) assert size > 0 P.InsertGlobalValues(my_fine_cell_ids, [int(basis_id)] * size, [0.] * size) for basis_id in my_restriction_supports: my_fine_cell_ids = my_restriction_supports[basis_id] size = len(my_fine_cell_ids) assert size > 0 ierr = P.InsertGlobalValues(my_fine_cell_ids, [int(basis_id)] * size, [1.] * size) assert ierr == 0 P.FillComplete(domain_map, range_map) a = sum_of_columns(P) assert np.all(a[:] == 1.0) return P
def __solve_one_step(self, rhs, RAP, R): # returns P*(RAP)^-1* R*rhs rhs_coarse = Epetra.Vector(R.DomainMap()) R.Multiply(True, rhs, rhs_coarse) if not np.max(np.abs(sum_of_columns(RAP))) < RAP.NormInf() * 1e-10: warnings.warn("sum of matrix columns does not equal to zero") # Set dirichlet boundary condition at a point if np.max(np.abs(sum_of_columns(RAP))) < RAP.NormInf() * 1e-10: row = 0 RAP = Epetra.CrsMatrix(RAP) RAP = epetra_set_matrow_to_zero(RAP, row=0) rhs_coarse = epetra_set_vecrow_to_zero(rhs_coarse, row=0) if row in RAP.Map().MyGlobalElements(): ierr = RAP.ReplaceGlobalValues([row], [row], 1.0) assert ierr == 0 sol_coarse = solve_direct(RAP, rhs_coarse) sol_fine = Epetra.Vector(self.P.RangeMap()) self.P.Multiply(False, sol_coarse, sol_fine) return sol_fine
def __init__(self): self.matrices = { 'A': Epetra.CrsMatrix(Epetra.Copy, std_map, 5), 'b': Epetra.Vector(std_map) } self.std_map = {1: std_map}
def __init__(self, comm, number_of_elements=10): self.comm = comm self.rank = comm.MyPID() self.size = comm.NumProc() if self.rank == 0: number_of_rows = number_of_elements else: number_of_rows = 0 unbalanced_map = Epetra.Map(-1, number_of_rows, 0, self.comm) self.A = Epetra.CrsMatrix(Epetra.Copy, unbalanced_map, 3) self.x = Epetra.Vector(unbalanced_map) self.b = Epetra.Vector(unbalanced_map) for gid in unbalanced_map.MyGlobalElements(): if gid == 0: self.A.InsertGlobalValues(gid, [1], [gid]) self.b[0] = -1 elif gid == (number_of_elements - 1): self.A.InsertGlobalValues(gid, [1], [gid]) self.b[-1] = 1 else: self.A.InsertGlobalValues(gid, [-1, 2, -1], [gid - 1, gid, gid + 1]) #optimizes storage self.A.FillComplete()
def get_inverse_tril(self, A, rows): """ Obter a matriz inversa de A obs: A deve ser quadrada input: A: CrsMatrix rows: numero de linhas output: INV: CrsMatrix inversa de A """ num_cols = A.NumMyCols() num_rows = A.NumMyRows() assert num_cols == num_rows map1 = Epetra.Map(rows, 0, self.comm) Inv = Epetra.CrsMatrix(Epetra.Copy, map1, 3) for i in range(rows): b = Epetra.Vector(map1) b[i] = 1.0 x = self.solve_linear_problem(A, b, rows) lines = np.nonzero(x[:])[0].astype(np.int32) col = np.repeat(i, len(lines)).astype(np.int32) Inv.InsertGlobalValues(lines, col, x[lines]) return Inv
def scipy_csr_matrix2CrsMatrix(sp, comm): Ap = sp.indptr Aj = sp.indices Ax = sp.data m = Ap.shape[0]-1 aMap = Epetra.Map(m, 0, comm) # range Map arMap=Epetra.Map(sp.shape[0], 0, comm) # domain Map adMap=Epetra.Map(sp.shape[1], 0, comm) aGraph = Epetra.CrsGraph( Epetra.Copy, aMap, 0) for ii in range(aMap.NumGlobalElements()): i = aMap.GID(ii) indy = range(Ap[i],Ap[i+1]) if (indy != []): aGraph.InsertGlobalIndices(i, Aj[indy]) aGraph.FillComplete(adMap, arMap) A = Epetra.CrsMatrix(Epetra.Copy, aGraph) for ii in range(aMap.NumGlobalElements()): i = aMap.GID(ii) indy = range(Ap[i],Ap[i+1]) if (indy != []): A.SumIntoGlobalValues(i, Ax[indy], Aj[indy]) A.FillComplete(adMap, arMap) return A
def __init_jacobian(self): """ Initialize Jacobian based on the row and column maps of the balanced field graph. """ field_graph = self.get_balanced_field_graph() self.__jac = Epetra.CrsMatrix(Epetra.Copy, field_graph) return
def __init__(self, mesh, interpolation_method=None, x=None): self.comm = Epetra.PyComm() std_map = Epetra.Map(len(mesh.all_volumes), 0, self.comm) self.T = Epetra.CrsMatrix(Epetra.Copy, std_map, 0) self.Q = Epetra.Vector(std_map) if x is None: self.x = Epetra.Vector(std_map) else: self.x = x
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 permutation_matrix(self): """ G eh a matriz permutacao """ self.map_global = dict(zip(self.all_volumes, range(self.nf))) global_map = list(range(self.nf)) wirebasket_map = [self.map_global[i] for i in self.elems_wirebasket] global_map = np.array(global_map).astype(np.int32) wirebasket_map = np.array(wirebasket_map).astype(np.int32) std_map = Epetra.Map(self.nf, 0, self.comm) G = Epetra.CrsMatrix(Epetra.Copy, std_map, 1) GT = Epetra.CrsMatrix(Epetra.Copy, std_map, 1) G.InsertGlobalValues(wirebasket_map, global_map, np.ones(self.nf, dtype=np.float64)) return G, GT
def __init__(self, mesh_data, x=None, mobility=None): """Init class.""" self.mesh_data = mesh_data self.mb = mesh_data.mb self.mtu = mesh_data.mtu self.comm = Epetra.PyComm() self.dirichlet_tag = mesh_data.dirichlet_tag self.neumann_tag = mesh_data.neumann_tag self.perm_tag = mesh_data.perm_tag self.source_tag = mesh_data.source_tag self.global_id_tag = mesh_data.global_id_tag self.volume_centre_tag = mesh_data.volume_centre_tag self.pressure_tag = mesh_data.pressure_tag self.flux_info_tag = self.mb.tag_get_handle( "flux info", 7, types.MB_TYPE_DOUBLE, types.MB_TAG_SPARSE, True ) self.normal_tag = self.mb.tag_get_handle( "Normal", 3, types.MB_TYPE_DOUBLE, types.MB_TAG_SPARSE, True ) self.dirichlet_nodes = set( self.mb.get_entities_by_type_and_tag( 0, types.MBVERTEX, self.dirichlet_tag, np.array((None,)) ) ) self.neumann_nodes = set( self.mb.get_entities_by_type_and_tag( 0, types.MBVERTEX, self.neumann_tag, np.array((None,)) ) ) self.neumann_nodes = self.neumann_nodes - self.dirichlet_nodes boundary_nodes = self.dirichlet_nodes | self.neumann_nodes self.intern_nodes = set(self.mesh_data.all_nodes) - boundary_nodes self.dirichlet_faces = mesh_data.dirichlet_faces self.neumann_faces = mesh_data.neumann_faces self.intern_faces = mesh_data.intern_faces() # self.intern_faces = set(mesh_data.all_faces).difference( # self.dirichlet_faces | self.neumann_faces # ) self.volumes = self.mesh_data.all_volumes std_map = Epetra.Map(len(self.volumes), 0, self.comm) self.T = Epetra.CrsMatrix(Epetra.Copy, std_map, 0) self.Q = Epetra.Vector(std_map) if x is None: self.x = Epetra.Vector(std_map) else: self.x = x
def mat_multiply(A, B, transpose_1=False, transpose_2=False, fill=30): """ Matrix product of two matrices Parameters ---------- A: Epetra Matrix B: Epetra Matrix transpose_1: bool, optional If true, then A is transposed before multiplication transpose_2: bool, optional If true, then B is transposed before multiplication fill: int, optional estimate of how many nonzeros per row Returns ------- C: Epetra Matrix C = A*B """ if transpose_1: C = Epetra.CrsMatrix(Epetra.Copy, A.DomainMap(), fill) else: C = Epetra.CrsMatrix(Epetra.Copy, A.RangeMap(), fill) ierr = EpetraExt.Multiply(A, transpose_1, B, transpose_2, C) assert ierr == 0 if transpose_1: C.FillComplete(B.DomainMap(), A.DomainMap()) else: C.FillComplete() if not (transpose_1 or transpose_2): assert (C.NumGlobalRows(), C.NumGlobalCols()) == (A.NumGlobalRows(), B.NumGlobalCols()) if transpose_1 and not transpose_2: assert (C.NumGlobalRows(), C.NumGlobalCols()) == (A.NumGlobalCols(), B.NumGlobalCols()) if not transpose_1 and transpose_2: assert (C.NumGlobalRows(), C.NumGlobalCols()) == (A.NumGlobalRows(), B.NumGlobalRows()) return C
def diagonal_inverse(A, scalar=1.0): map = A.RangeMap() v_diagonal = Epetra.Vector(map) A.ExtractDiagonalCopy(v_diagonal) v_diagonal_inv = 1. / v_diagonal[:] D_inv = Epetra.CrsMatrix(Epetra.Copy, map, 1) row_inds = D_inv.Map().MyGlobalElements() D_inv.InsertGlobalValues(row_inds, row_inds, scalar * v_diagonal_inv) D_inv.FillComplete() return D_inv
def create_matrix(self, dim, name, share=False): if name not in self.matrix and name not in self.not_shared_matrices: # The last argument suppose that our meshes will be # mostly tetrahedral self.matrix[name] = Epetra.CrsMatrix(Epetra.Copy, self.std_map[dim], 5) if not share: self.not_shared_matrices.add(name) elif not share or name in self.not_shared_matrices: raise KeyError("Matrix name ({0}) already defined and share " "is set to False".format(name))
def __init__(self, A, my_restriction_supports, my_basis_supports): if len(my_basis_supports) < len(my_restriction_supports): raise ValueError() self.A = A map = self.A.RangeMap() self.P = self._prolongation_operator_init(map, my_restriction_supports, my_basis_supports) self.P_initial = Epetra.CrsMatrix(self.P) self.R = self._create_structure_matrix(map, my_restriction_supports) self.N = self._create_structure_matrix( map, my_basis_supports) # Allowed nonzeros structure of P self.delta_P = Epetra.CrsMatrix(self.N) self.delta_P.PutScalar(0.0) self.num_overlaps = sum_of_columns(self.N) sum_cols_P = sum_of_columns(self.P) assert np.allclose(sum_cols_P[:], 1.0) a = sum_of_columns(self.R) assert np.all(a[:] == 1.0)
def get_CrsMatrix_by_inds(comm, inds): """ retorna uma CrsMatrix a partir de inds input: inds: array numpy com informacoes da matriz output: A: CrsMatrix """ rows = inds[3][0] cols = inds[3][1] row_map = Epetra.Map(rows, 0, comm) col_map = Epetra.Map(cols, 0, comm) A = Epetra.CrsMatrix(Epetra.Copy, row_map, col_map, 7) A.InsertGlobalValues(inds[0], inds[1], inds[2]) return A
def transpose_matrix(A): """ Transposes a matrix Parameters ---------- A: Epetra Matrix Returns ------- C: transpose of matrix A """ V = Epetra.Vector(A.RangeMap()) V.PutScalar(1.0) I = diagonal_matrix_from_vector(V, A.RangeMap()) C = Epetra.CrsMatrix(Epetra.Copy, A.DomainMap(), 10) EpetraExt.Multiply(A, True, I, False, C) C.FillComplete() return C
def __init__(self, rows, cols, bandwidth=1, sizeHint=None, matrix=None): """Instantiates and wraps an `Epetra.CrsMatrix` Parameters ---------- rows : int The number of matrix rows cols : int The number of matrix columns bandwidth : int The proposed band width of the matrix. sizeHint : int Estimate of the number of non-zeros matrix : ~PyTrilinos.Epetra.CrsMatrix Pre-assembled Trilinos matrix to use for storage. """ self.rows = rows self.cols = cols size = max(rows, cols) if sizeHint is not None and bandwidth == 0: bandwidth = (sizeHint + size - 1) // (size or 1) else: bandwidth = bandwidth if matrix is None: # On Mar 26, 2011, at 11:04 AM, Williams, Alan B <*****@*****.**> wrote: # # In almost every case, it is advisable to construct epetra # matrices with only a row-map and allow the column-map to be # generated internally. Especially if you have a rectangular # matrix, which is even trickier to get correct. matrix = Epetra.CrsMatrix(Epetra.Copy, self.rowMap, (bandwidth * 3) // 2) # Leave extra bandwidth, to handle multiple insertions into the # same spot. It's memory-inefficient, but it'll get cleaned up when # FillComplete is called, and according to the Trilinos devs the # performance boost will be worth it. super(_TrilinosMatrixFromShape, self).__init__(matrix=matrix, bandwidth=bandwidth)
def _getDistributedMatrix(self): """ Returns an equivalent Trilinos matrix, but redistributed evenly over all processors. """ if self.comm.NumProc() == 1: return self.matrix # No redistribution necessary in serial mode else: ## self.matrix.GlobalAssemble() totalElements = self.matrix.NumGlobalRows() DistributedMap = Epetra.Map(totalElements, 0, self.comm) RootToDist = Epetra.Import(DistributedMap, self.nonOverlappingMap) DistMatrix = Epetra.CrsMatrix(Epetra.Copy, DistributedMap, self.bandwidth*3/2) DistMatrix.Import(self.matrix, RootToDist, Epetra.Insert) return DistMatrix
def pymultimat(self, A, B, nf, transpose_A=False, transpose_B=False): """ Multiplica a matriz A pela matriz B ambas de mesma ordem e quadradas nf: ordem da matriz """ if A.Filled() == False: A.FillComplete() if B.Filled() == False: B.FillComplete() nf_map = Epetra.Map(nf, 0, self.comm) C = Epetra.CrsMatrix(Epetra.Copy, nf_map, 3) EpetraExt.Multiply(A, transpose_A, B, transpose_B, C) # C.FillComplete() return C
def get_CrsMatrix_by_array(self, M, n_rows=None, n_cols=None): """ retorna uma CrsMatrix a partir de um array numpy input: M: array numpy (matriz) n_rows: (opcional) numero de linhas da matriz A n_cols: (opcional) numero de colunas da matriz A output: A: CrsMatrix """ if n_rows == None and n_cols == None: rows, cols = M.shape else: if n_rows == None or n_cols == None: print('determine n_rows e n_cols') sys.exit(0) else: rows = n_rows cols = n_cols row_map = Epetra.Map(rows, 0, self.comm) col_map = Epetra.Map(cols, 0, self.comm) A = Epetra.CrsMatrix(Epetra.Copy, row_map, col_map, 7) rows = np.nonzero(M)[0].astype(np.int32) cols = np.nonzero(M)[1].astype(np.int32) if self.verif == True: print(rows) print(cols) print(M[rows, cols]) import pdb pdb.set_trace() A.InsertGlobalValues(rows, cols, M[rows, cols]) return A
def _getDistributedMatrix(self): """ Returns an equivalent Trilinos matrix, but redistributed evenly over all processors. """ if self.comm.NumProc() == 1: return self.matrix # No redistribution necessary in serial mode else: ## self._matrix.GlobalAssemble() totalElements = self.matrix.NumGlobalRows() # Epetra.Map(numGlobalElements, indexBase, comm) # implicit number of elements per processor DistributedMap = Epetra.Map(totalElements, 0, self.comm) RootToDist = Epetra.Import(DistributedMap, self.rangeMap) DistMatrix = Epetra.CrsMatrix(Epetra.Copy, DistributedMap, (self.bandwidth * 3) // 2) DistMatrix.Import(self.matrix, RootToDist, Epetra.Insert) return DistMatrix
def pymultimat(comm, A, B, transpose_A=False, transpose_B=False): """ Multiplica a matriz A pela matriz B ambas de mesma ordem e quadradas nf: ordem da matriz """ assert A.NumMyCols() == A.NumMyRows() assert B.NumMyCols() == B.NumMyRows() assert A.NumMyRows() == B.NumMyRows() n = A.NumMyCols() if A.Filled() == False: A.FillComplete() if B.Filled() == False: B.FillComplete() nf_map = Epetra.Map(n, 0, comm) C = Epetra.CrsMatrix(Epetra.Copy, nf_map, 3) EpetraExt.Multiply(A, transpose_A, B, transpose_B, C) return C
def modificar_matriz(self, A, rows, columns, walk_rows, return_inds=False): """ Modifica a matriz A para o tamanho (rows x columns) input: walk_rows: linhas para caminhar na matriz A rows: numero de linhas da nova matriz (C) columns: numero de colunas da nova matriz (C) return_inds: se return_inds = True retorna os indices das linhas, colunas e respectivos valores output: C: CrsMatrix rows x columns """ lines = np.array([], dtype=np.int32) cols = lines.copy() valuesM = np.array([], dtype='float64') sz = [rows, columns] row_map = Epetra.Map(rows, 0, self.comm) col_map = Epetra.Map(columns, 0, self.comm) C = Epetra.CrsMatrix(Epetra.Copy, row_map, col_map, 3) for i in range(walk_rows): p = A.ExtractGlobalRowCopy(i) values = p[0] index_columns = p[1] C.InsertGlobalValues(i, values, index_columns) lines = np.append(lines, np.repeat(i, len(values))) cols = np.append(cols, p[1]) valuesM = np.append(valuesM, p[0]) if return_inds == True: inds = [lines, cols, valuesM, sz] return C, inds else: return C
def get_CrsMatrix_by_inds(inds, comm): """ retorna uma CrsMatrix a partir de inds input: inds: array numpy com informacoes da matriz output: A: CrsMatrix """ rows = inds[3][0] cols = inds[3][1] row_map = Epetra.Map(rows, 0, comm) col_map = Epetra.Map(cols, 0, comm) A = Epetra.CrsMatrix(Epetra.Copy, row_map, col_map, 7) if len(inds[4]) < 1: A.InsertGlobalValues(inds[0], inds[1], inds[2]) else: A.InsertGlobalValues(inds[4], inds[5], inds[2]) # else: # raise ValueError("especifique true ou false para slice") return A