hypre_ParCSRMatrix * hypre_ParCSRBlockMatrixCompress( hypre_ParCSRBlockMatrix *matrix ) { MPI_Comm comm = hypre_ParCSRBlockMatrixComm(matrix); hypre_CSRBlockMatrix *diag = hypre_ParCSRBlockMatrixDiag(matrix); hypre_CSRBlockMatrix *offd = hypre_ParCSRBlockMatrixOffd(matrix); HYPRE_Int global_num_rows = hypre_ParCSRBlockMatrixGlobalNumRows(matrix); HYPRE_Int global_num_cols = hypre_ParCSRBlockMatrixGlobalNumCols(matrix); HYPRE_Int *row_starts = hypre_ParCSRBlockMatrixRowStarts(matrix); HYPRE_Int *col_starts = hypre_ParCSRBlockMatrixColStarts(matrix); HYPRE_Int num_cols_offd = hypre_CSRBlockMatrixNumCols(offd); HYPRE_Int num_nonzeros_diag = hypre_CSRBlockMatrixNumNonzeros(diag); HYPRE_Int num_nonzeros_offd = hypre_CSRBlockMatrixNumNonzeros(offd); hypre_ParCSRMatrix *matrix_C; HYPRE_Int i; matrix_C = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols, row_starts,col_starts,num_cols_offd,num_nonzeros_diag,num_nonzeros_offd); hypre_ParCSRMatrixInitialize(matrix_C); hypre_CSRMatrixDestroy(hypre_ParCSRMatrixDiag(matrix_C)); hypre_ParCSRMatrixDiag(matrix_C) = hypre_CSRBlockMatrixCompress(diag); hypre_CSRMatrixDestroy(hypre_ParCSRMatrixOffd(matrix_C)); hypre_ParCSRMatrixOffd(matrix_C) = hypre_CSRBlockMatrixCompress(offd); for(i = 0; i < num_cols_offd; i++) hypre_ParCSRMatrixColMapOffd(matrix_C)[i] = hypre_ParCSRBlockMatrixColMapOffd(matrix)[i]; return matrix_C; }
HYPRE_Int hypre_ParCSRBlockMatrixSetDNumNonzeros( hypre_ParCSRBlockMatrix *matrix) { MPI_Comm comm = hypre_ParCSRBlockMatrixComm(matrix); hypre_CSRBlockMatrix *diag = hypre_ParCSRBlockMatrixDiag(matrix); HYPRE_Int *diag_i = hypre_CSRBlockMatrixI(diag); hypre_CSRBlockMatrix *offd = hypre_ParCSRBlockMatrixOffd(matrix); HYPRE_Int *offd_i = hypre_CSRBlockMatrixI(offd); HYPRE_Int local_num_rows = hypre_CSRBlockMatrixNumRows(diag); HYPRE_Real total_num_nonzeros; HYPRE_Real local_num_nonzeros; HYPRE_Int ierr = 0; local_num_nonzeros = (HYPRE_Real) diag_i[local_num_rows] + (HYPRE_Real) offd_i[local_num_rows]; hypre_MPI_Allreduce(&local_num_nonzeros, &total_num_nonzeros, 1, HYPRE_MPI_REAL, hypre_MPI_SUM, comm); hypre_ParCSRBlockMatrixDNumNonzeros(matrix) = total_num_nonzeros; return ierr; }
HYPRE_Int hypre_ParCSRBlockMatrixMatvec(HYPRE_Complex alpha, hypre_ParCSRBlockMatrix *A, hypre_ParVector *x, HYPRE_Complex beta, hypre_ParVector *y) { hypre_ParCSRCommHandle *comm_handle; hypre_ParCSRCommPkg *comm_pkg; hypre_CSRBlockMatrix *diag, *offd; hypre_Vector *x_local, *y_local, *x_tmp; HYPRE_Int i, j, k, index, num_rows, num_cols; HYPRE_Int blk_size, x_size, y_size, size; HYPRE_Int num_cols_offd, start, finish, elem; HYPRE_Int ierr = 0, nprocs, num_sends, mypid; HYPRE_Complex *x_tmp_data, *x_buf_data, *x_local_data; hypre_MPI_Comm_size(hypre_ParCSRBlockMatrixComm(A), &nprocs); hypre_MPI_Comm_rank(hypre_ParCSRBlockMatrixComm(A), &mypid); comm_pkg = hypre_ParCSRBlockMatrixCommPkg(A); num_rows = hypre_ParCSRBlockMatrixGlobalNumRows(A); num_cols = hypre_ParCSRBlockMatrixGlobalNumCols(A); blk_size = hypre_ParCSRBlockMatrixBlockSize(A); diag = hypre_ParCSRBlockMatrixDiag(A); offd = hypre_ParCSRBlockMatrixOffd(A); num_cols_offd = hypre_CSRBlockMatrixNumCols(offd); x_local = hypre_ParVectorLocalVector(x); y_local = hypre_ParVectorLocalVector(y); x_size = hypre_ParVectorGlobalSize(x); y_size = hypre_ParVectorGlobalSize(y); x_local_data = hypre_VectorData(x_local); /*--------------------------------------------------------------------- * Check for size compatibility. *--------------------------------------------------------------------*/ if (num_cols*blk_size != x_size) ierr = 11; if (num_rows*blk_size != y_size) ierr = 12; if (num_cols*blk_size != x_size && num_rows*blk_size != y_size) ierr = 13; if (nprocs > 1) { x_tmp = hypre_SeqVectorCreate(num_cols_offd*blk_size); hypre_SeqVectorInitialize(x_tmp); x_tmp_data = hypre_VectorData(x_tmp); if (!comm_pkg) { hypre_BlockMatvecCommPkgCreate(A); comm_pkg = hypre_ParCSRBlockMatrixCommPkg(A); } num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg); size = hypre_ParCSRCommPkgSendMapStart(comm_pkg,num_sends)*blk_size; x_buf_data = hypre_CTAlloc(HYPRE_Complex, size); index = 0; for (i = 0; i < num_sends; i++) { start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i); finish = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); for (j = start; j < finish; j++) { elem = hypre_ParCSRCommPkgSendMapElmt(comm_pkg,j)*blk_size; for (k = 0; k < blk_size; k++) x_buf_data[index++] = x_local_data[elem++]; } } comm_handle = hypre_ParCSRBlockCommHandleCreate(1, blk_size,comm_pkg, x_buf_data, x_tmp_data); } hypre_CSRBlockMatrixMatvec(alpha, diag, x_local, beta, y_local); if (nprocs > 1) { hypre_ParCSRBlockCommHandleDestroy(comm_handle); comm_handle = NULL; if (num_cols_offd) hypre_CSRBlockMatrixMatvec(alpha,offd,x_tmp,1.0,y_local); hypre_SeqVectorDestroy(x_tmp); x_tmp = NULL; hypre_TFree(x_buf_data); } return ierr; }
hypre_CSRBlockMatrix * hypre_ParCSRBlockMatrixExtractBExt(hypre_ParCSRBlockMatrix *B, hypre_ParCSRBlockMatrix *A, HYPRE_Int data) { MPI_Comm comm = hypre_ParCSRBlockMatrixComm(B); HYPRE_Int first_col_diag = hypre_ParCSRBlockMatrixFirstColDiag(B); HYPRE_Int *col_map_offd = hypre_ParCSRBlockMatrixColMapOffd(B); HYPRE_Int block_size = hypre_ParCSRBlockMatrixBlockSize(B); hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRBlockMatrixCommPkg(A); HYPRE_Int num_recvs = hypre_ParCSRCommPkgNumRecvs(comm_pkg); HYPRE_Int *recv_vec_starts = hypre_ParCSRCommPkgRecvVecStarts(comm_pkg); HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg); HYPRE_Int *send_map_starts = hypre_ParCSRCommPkgSendMapStarts(comm_pkg); HYPRE_Int *send_map_elmts = hypre_ParCSRCommPkgSendMapElmts(comm_pkg); hypre_ParCSRCommHandle *comm_handle; hypre_ParCSRCommPkg *tmp_comm_pkg; hypre_CSRBlockMatrix *diag = hypre_ParCSRBlockMatrixDiag(B); HYPRE_Int *diag_i = hypre_CSRBlockMatrixI(diag); HYPRE_Int *diag_j = hypre_CSRBlockMatrixJ(diag); HYPRE_Complex *diag_data = hypre_CSRBlockMatrixData(diag); hypre_CSRBlockMatrix *offd = hypre_ParCSRBlockMatrixOffd(B); HYPRE_Int *offd_i = hypre_CSRBlockMatrixI(offd); HYPRE_Int *offd_j = hypre_CSRBlockMatrixJ(offd); HYPRE_Complex *offd_data = hypre_CSRBlockMatrixData(offd); HYPRE_Int *B_int_i; HYPRE_Int *B_int_j; HYPRE_Complex *B_int_data; HYPRE_Int num_cols_B, num_nonzeros; HYPRE_Int num_rows_B_ext; HYPRE_Int num_procs, my_id; hypre_CSRBlockMatrix *B_ext; HYPRE_Int *B_ext_i; HYPRE_Int *B_ext_j; HYPRE_Complex *B_ext_data; HYPRE_Int *jdata_recv_vec_starts; HYPRE_Int *jdata_send_map_starts; HYPRE_Int i, j, k, l, counter, bnnz; HYPRE_Int start_index; HYPRE_Int j_cnt, jrow; hypre_MPI_Comm_size(comm,&num_procs); hypre_MPI_Comm_rank(comm,&my_id); bnnz = block_size * block_size; num_cols_B = hypre_ParCSRMatrixGlobalNumCols(B); num_rows_B_ext = recv_vec_starts[num_recvs]; B_int_i = hypre_CTAlloc(HYPRE_Int, send_map_starts[num_sends]+1); B_ext_i = hypre_CTAlloc(HYPRE_Int, num_rows_B_ext+1); /*-------------------------------------------------------------------------- * generate B_int_i through adding number of row-elements of offd and diag * for corresponding rows. B_int_i[j+1] contains the number of elements of * a row j (which is determined through send_map_elmts) *--------------------------------------------------------------------------*/ B_int_i[0] = 0; j_cnt = 0; num_nonzeros = 0; for (i=0; i < num_sends; i++) { for (j = send_map_starts[i]; j < send_map_starts[i+1]; j++) { jrow = send_map_elmts[j]; B_int_i[++j_cnt] = offd_i[jrow+1] - offd_i[jrow] + diag_i[jrow+1] - diag_i[jrow]; num_nonzeros += B_int_i[j_cnt]; } } /*-------------------------------------------------------------------------- * initialize communication *--------------------------------------------------------------------------*/ comm_handle = hypre_ParCSRCommHandleCreate(11,comm_pkg, &B_int_i[1],&B_ext_i[1]); B_int_j = hypre_CTAlloc(HYPRE_Int, num_nonzeros); if (data) B_int_data = hypre_CTAlloc(HYPRE_Complex, num_nonzeros*bnnz); jdata_send_map_starts = hypre_CTAlloc(HYPRE_Int, num_sends+1); jdata_recv_vec_starts = hypre_CTAlloc(HYPRE_Int, num_recvs+1); start_index = B_int_i[0]; jdata_send_map_starts[0] = start_index; counter = 0; for (i=0; i < num_sends; i++) { num_nonzeros = counter; for (j = send_map_starts[i]; j < send_map_starts[i+1]; j++) { jrow = send_map_elmts[j]; for (k=diag_i[jrow]; k < diag_i[jrow+1]; k++) { B_int_j[counter] = diag_j[k]+first_col_diag; if (data) { for(l = 0; l < bnnz; l++) B_int_data[counter*bnnz+ l] = diag_data[k*bnnz+ l]; } counter++; } for (k=offd_i[jrow]; k < offd_i[jrow+1]; k++) { B_int_j[counter] = col_map_offd[offd_j[k]]; if (data) { for(l = 0; l < bnnz; l++) B_int_data[counter*bnnz+ l] = offd_data[k*bnnz+ l]; } counter++; } } num_nonzeros = counter - num_nonzeros; start_index += num_nonzeros; jdata_send_map_starts[i+1] = start_index; } tmp_comm_pkg = hypre_CTAlloc(hypre_ParCSRCommPkg,1); hypre_ParCSRCommPkgComm(tmp_comm_pkg) = comm; hypre_ParCSRCommPkgNumSends(tmp_comm_pkg) = num_sends; hypre_ParCSRCommPkgNumRecvs(tmp_comm_pkg) = num_recvs; hypre_ParCSRCommPkgSendProcs(tmp_comm_pkg) = hypre_ParCSRCommPkgSendProcs(comm_pkg); hypre_ParCSRCommPkgRecvProcs(tmp_comm_pkg) = hypre_ParCSRCommPkgRecvProcs(comm_pkg); hypre_ParCSRCommPkgSendMapStarts(tmp_comm_pkg) = jdata_send_map_starts; hypre_ParCSRCommHandleDestroy(comm_handle); comm_handle = NULL; /*-------------------------------------------------------------------------- * after communication exchange B_ext_i[j+1] contains the number of elements * of a row j ! * evaluate B_ext_i and compute num_nonzeros for B_ext *--------------------------------------------------------------------------*/ for (i=0; i < num_recvs; i++) for (j = recv_vec_starts[i]; j < recv_vec_starts[i+1]; j++) B_ext_i[j+1] += B_ext_i[j]; num_nonzeros = B_ext_i[num_rows_B_ext]; B_ext = hypre_CSRBlockMatrixCreate(block_size, num_rows_B_ext, num_cols_B, num_nonzeros); B_ext_j = hypre_CTAlloc(HYPRE_Int, num_nonzeros); if (data) B_ext_data = hypre_CTAlloc(HYPRE_Complex, num_nonzeros*bnnz); for (i=0; i < num_recvs; i++) { start_index = B_ext_i[recv_vec_starts[i]]; num_nonzeros = B_ext_i[recv_vec_starts[i+1]]-start_index; jdata_recv_vec_starts[i+1] = B_ext_i[recv_vec_starts[i+1]]; } hypre_ParCSRCommPkgRecvVecStarts(tmp_comm_pkg) = jdata_recv_vec_starts; comm_handle = hypre_ParCSRCommHandleCreate(11,tmp_comm_pkg,B_int_j,B_ext_j); hypre_ParCSRCommHandleDestroy(comm_handle); comm_handle = NULL; if (data) { comm_handle = hypre_ParCSRBlockCommHandleCreate(1, bnnz,tmp_comm_pkg, B_int_data, B_ext_data); hypre_ParCSRBlockCommHandleDestroy(comm_handle); comm_handle = NULL; } hypre_CSRBlockMatrixI(B_ext) = B_ext_i; hypre_CSRBlockMatrixJ(B_ext) = B_ext_j; if (data) hypre_CSRBlockMatrixData(B_ext) = B_ext_data; hypre_TFree(B_int_i); hypre_TFree(B_int_j); if (data) hypre_TFree(B_int_data); hypre_TFree(jdata_send_map_starts); hypre_TFree(jdata_recv_vec_starts); hypre_TFree(tmp_comm_pkg); return B_ext; }
HYPRE_Int hypre_BlockMatvecCommPkgCreate(hypre_ParCSRBlockMatrix *A) { #ifdef HYPRE_NO_GLOBAL_PARTITION HYPRE_Int col_start = 0, col_end = 0; HYPRE_Int num_recvs, *recv_procs, *recv_vec_starts; HYPRE_Int num_sends, *send_procs, *send_map_starts; HYPRE_Int *send_map_elmts; HYPRE_Int num_cols_off_d; HYPRE_Int *col_map_off_d; HYPRE_Int first_col_diag; HYPRE_Int global_num_cols; MPI_Comm comm; hypre_ParCSRCommPkg *comm_pkg; hypre_IJAssumedPart *apart; /*----------------------------------------------------------- * get parcsr_A information *----------------------------------------------------------*/ col_start = hypre_ParCSRBlockMatrixFirstColDiag(A); col_end = hypre_ParCSRBlockMatrixLastColDiag(A); col_map_off_d = hypre_ParCSRBlockMatrixColMapOffd(A); num_cols_off_d = hypre_CSRBlockMatrixNumCols(hypre_ParCSRBlockMatrixOffd(A)); global_num_cols = hypre_ParCSRBlockMatrixGlobalNumCols(A); comm = hypre_ParCSRBlockMatrixComm(A); first_col_diag = hypre_ParCSRBlockMatrixFirstColDiag(A); /* Create the assumed partition */ if (hypre_ParCSRBlockMatrixAssumedPartition(A) == NULL) { hypre_ParCSRBlockMatrixCreateAssumedPartition(A); } apart = hypre_ParCSRBlockMatrixAssumedPartition(A); /*----------------------------------------------------------- * get commpkg info information *----------------------------------------------------------*/ hypre_NewCommPkgCreate_core( comm, col_map_off_d, first_col_diag, col_start, col_end, num_cols_off_d, global_num_cols, &num_recvs, &recv_procs, &recv_vec_starts, &num_sends, &send_procs, &send_map_starts, &send_map_elmts, apart); if (!num_recvs) { hypre_TFree(recv_procs); recv_procs = NULL; } if (!num_sends) { hypre_TFree(send_procs); hypre_TFree(send_map_elmts); send_procs = NULL; send_map_elmts = NULL; } #else hypre_ParCSRCommPkg *comm_pkg; MPI_Comm comm = hypre_ParCSRBlockMatrixComm(A); HYPRE_Int num_sends; HYPRE_Int *send_procs; HYPRE_Int *send_map_starts; HYPRE_Int *send_map_elmts; HYPRE_Int num_recvs; HYPRE_Int *recv_procs; HYPRE_Int *recv_vec_starts; HYPRE_Int *col_map_offd = hypre_ParCSRBlockMatrixColMapOffd(A); HYPRE_Int first_col_diag = hypre_ParCSRBlockMatrixFirstColDiag(A); HYPRE_Int *col_starts = hypre_ParCSRBlockMatrixColStarts(A); HYPRE_Int num_cols_diag = hypre_CSRBlockMatrixNumCols(hypre_ParCSRBlockMatrixDiag(A)); HYPRE_Int num_cols_offd = hypre_CSRBlockMatrixNumCols(hypre_ParCSRBlockMatrixOffd(A)); hypre_MatvecCommPkgCreate_core(comm, col_map_offd, first_col_diag, col_starts, num_cols_diag, num_cols_offd, first_col_diag, col_map_offd, 1, &num_recvs, &recv_procs, &recv_vec_starts, &num_sends, &send_procs, &send_map_starts, &send_map_elmts); #endif /*----------------------------------------------------------- * setup commpkg *----------------------------------------------------------*/ comm_pkg = hypre_CTAlloc(hypre_ParCSRCommPkg, 1); hypre_ParCSRCommPkgComm(comm_pkg) = comm; hypre_ParCSRCommPkgNumRecvs(comm_pkg) = num_recvs; hypre_ParCSRCommPkgRecvProcs(comm_pkg) = recv_procs; hypre_ParCSRCommPkgRecvVecStarts(comm_pkg) = recv_vec_starts; hypre_ParCSRCommPkgNumSends(comm_pkg) = num_sends; hypre_ParCSRCommPkgSendProcs(comm_pkg) = send_procs; hypre_ParCSRCommPkgSendMapStarts(comm_pkg) = send_map_starts; hypre_ParCSRCommPkgSendMapElmts(comm_pkg) = send_map_elmts; hypre_ParCSRBlockMatrixCommPkg(A) = comm_pkg; return hypre_error_flag; }
hypre_ParCSRMatrix * hypre_ParCSRBlockMatrixConvertToParCSRMatrix(hypre_ParCSRBlockMatrix *matrix) { MPI_Comm comm = hypre_ParCSRBlockMatrixComm(matrix); hypre_CSRBlockMatrix *diag = hypre_ParCSRBlockMatrixDiag(matrix); hypre_CSRBlockMatrix *offd = hypre_ParCSRBlockMatrixOffd(matrix); HYPRE_Int block_size = hypre_ParCSRBlockMatrixBlockSize(matrix); HYPRE_Int global_num_rows = hypre_ParCSRBlockMatrixGlobalNumRows(matrix); HYPRE_Int global_num_cols = hypre_ParCSRBlockMatrixGlobalNumCols(matrix); HYPRE_Int *row_starts = hypre_ParCSRBlockMatrixRowStarts(matrix); HYPRE_Int *col_starts = hypre_ParCSRBlockMatrixColStarts(matrix); HYPRE_Int num_cols_offd = hypre_CSRBlockMatrixNumCols(offd); HYPRE_Int num_nonzeros_diag = hypre_CSRBlockMatrixNumNonzeros(diag); HYPRE_Int num_nonzeros_offd = hypre_CSRBlockMatrixNumNonzeros(offd); hypre_ParCSRMatrix *matrix_C; HYPRE_Int *matrix_C_row_starts; HYPRE_Int *matrix_C_col_starts; HYPRE_Int *counter, *new_j_map; HYPRE_Int size_j, size_map, index, new_num_cols, removed = 0; HYPRE_Int *offd_j, *col_map_offd, *new_col_map_offd; HYPRE_Int num_procs, i, j; hypre_CSRMatrix *diag_nozeros, *offd_nozeros; hypre_MPI_Comm_size(comm,&num_procs); #ifdef HYPRE_NO_GLOBAL_PARTITION matrix_C_row_starts = hypre_CTAlloc(HYPRE_Int, 2); matrix_C_col_starts = hypre_CTAlloc(HYPRE_Int, 2); for(i = 0; i < 2; i++) { matrix_C_row_starts[i] = row_starts[i]*block_size; matrix_C_col_starts[i] = col_starts[i]*block_size; } #else matrix_C_row_starts = hypre_CTAlloc(HYPRE_Int, num_procs + 1); matrix_C_col_starts = hypre_CTAlloc(HYPRE_Int, num_procs + 1); for(i = 0; i < num_procs + 1; i++) { matrix_C_row_starts[i] = row_starts[i]*block_size; matrix_C_col_starts[i] = col_starts[i]*block_size; } #endif matrix_C = hypre_ParCSRMatrixCreate(comm, global_num_rows*block_size, global_num_cols*block_size, matrix_C_row_starts, matrix_C_col_starts, num_cols_offd*block_size, num_nonzeros_diag*block_size*block_size, num_nonzeros_offd*block_size*block_size); hypre_ParCSRMatrixInitialize(matrix_C); /* DIAG */ hypre_CSRMatrixDestroy(hypre_ParCSRMatrixDiag(matrix_C)); hypre_ParCSRMatrixDiag(matrix_C) = hypre_CSRBlockMatrixConvertToCSRMatrix(diag); /* AB - added to delete zeros */ diag_nozeros = hypre_CSRMatrixDeleteZeros( hypre_ParCSRMatrixDiag(matrix_C), 1e-14); if(diag_nozeros) { hypre_CSRMatrixDestroy(hypre_ParCSRMatrixDiag(matrix_C)); hypre_ParCSRMatrixDiag(matrix_C) = diag_nozeros; } /* OFF-DIAG */ hypre_CSRMatrixDestroy(hypre_ParCSRMatrixOffd(matrix_C)); hypre_ParCSRMatrixOffd(matrix_C) = hypre_CSRBlockMatrixConvertToCSRMatrix(offd); /* AB - added to delete zeros - this just deletes from data and j arrays */ offd_nozeros = hypre_CSRMatrixDeleteZeros( hypre_ParCSRMatrixOffd(matrix_C), 1e-14); if(offd_nozeros) { hypre_CSRMatrixDestroy(hypre_ParCSRMatrixOffd(matrix_C)); hypre_ParCSRMatrixOffd(matrix_C) = offd_nozeros; removed = 1; } /* now convert the col_map_offd */ for (i = 0; i < num_cols_offd; i++) for (j = 0; j < block_size; j++) hypre_ParCSRMatrixColMapOffd(matrix_C)[i*block_size + j] = hypre_ParCSRBlockMatrixColMapOffd(matrix)[i]*block_size + j; /* if we deleted zeros, then it is possible that col_map_offd can be compressed as well - this requires some amount of work that could be skipped... */ if (removed) { size_map = num_cols_offd*block_size; counter = hypre_CTAlloc(HYPRE_Int, size_map); new_j_map = hypre_CTAlloc(HYPRE_Int, size_map); offd_j = hypre_CSRMatrixJ(hypre_ParCSRMatrixOffd(matrix_C)); col_map_offd = hypre_ParCSRMatrixColMapOffd(matrix_C); size_j = hypre_CSRMatrixNumNonzeros(hypre_ParCSRMatrixOffd(matrix_C)); /* mark which off_d entries are found in j */ for (i=0; i < size_j; i++) { counter[offd_j[i]] = 1; } /*now find new numbering for columns (we will delete the cols where counter = 0*/ index = 0; for (i=0; i < size_map; i++) { if (counter[i]) new_j_map[i] = index++; } new_num_cols = index; /* if there are some col entries to remove: */ if (!(index == size_map)) { /* go thru j and adjust entries */ for (i=0; i < size_j; i++) { offd_j[i] = new_j_map[offd_j[i]]; } /*now go thru col map and get rid of non-needed entries */ new_col_map_offd = hypre_CTAlloc(HYPRE_Int, new_num_cols); index = 0; for (i=0; i < size_map; i++) { if (counter[i]) { new_col_map_offd[index++] = col_map_offd[i]; } } /* set the new col map */ hypre_TFree(col_map_offd); hypre_ParCSRMatrixColMapOffd(matrix_C) = new_col_map_offd; /* modify the number of cols */ hypre_CSRMatrixNumCols(hypre_ParCSRMatrixOffd(matrix_C)) = new_num_cols; } hypre_TFree(new_j_map); hypre_TFree(counter); } hypre_ParCSRMatrixSetNumNonzeros( matrix_C ); hypre_ParCSRMatrixSetDNumNonzeros( matrix_C ); /* we will not copy the comm package */ hypre_ParCSRMatrixCommPkg(matrix_C) = NULL; return matrix_C; }
hypre_ParCSRBlockMatrix * hypre_ParCSRBlockMatrixCreate( MPI_Comm comm, HYPRE_Int block_size, HYPRE_Int global_num_rows, HYPRE_Int global_num_cols, HYPRE_Int *row_starts, HYPRE_Int *col_starts, HYPRE_Int num_cols_offd, HYPRE_Int num_nonzeros_diag, HYPRE_Int num_nonzeros_offd ) { hypre_ParCSRBlockMatrix *matrix; HYPRE_Int num_procs, my_id; HYPRE_Int local_num_rows, local_num_cols; HYPRE_Int first_row_index, first_col_diag; matrix = hypre_CTAlloc(hypre_ParCSRBlockMatrix, 1); hypre_MPI_Comm_rank(comm,&my_id); hypre_MPI_Comm_size(comm,&num_procs); if (!row_starts) { #ifdef HYPRE_NO_GLOBAL_PARTITION hypre_GenerateLocalPartitioning(global_num_rows, num_procs, my_id, &row_starts); #else hypre_GeneratePartitioning(global_num_rows,num_procs,&row_starts); #endif } if (!col_starts) { if (global_num_rows == global_num_cols) { col_starts = row_starts; } else { #ifdef HYPRE_NO_GLOBAL_PARTITION hypre_GenerateLocalPartitioning(global_num_cols, num_procs, my_id, &col_starts); #else hypre_GeneratePartitioning(global_num_cols,num_procs,&col_starts); #endif } } #ifdef HYPRE_NO_GLOBAL_PARTITION /* row_starts[0] is start of local rows. row_starts[1] is start of next processor's rows */ first_row_index = row_starts[0]; local_num_rows = row_starts[1]-first_row_index ; first_col_diag = col_starts[0]; local_num_cols = col_starts[1]-first_col_diag; #else first_row_index = row_starts[my_id]; local_num_rows = row_starts[my_id+1]-first_row_index; first_col_diag = col_starts[my_id]; local_num_cols = col_starts[my_id+1]-first_col_diag; #endif hypre_ParCSRBlockMatrixComm(matrix) = comm; hypre_ParCSRBlockMatrixDiag(matrix) = hypre_CSRBlockMatrixCreate(block_size, local_num_rows,local_num_cols,num_nonzeros_diag); hypre_ParCSRBlockMatrixOffd(matrix) = hypre_CSRBlockMatrixCreate(block_size, local_num_rows, num_cols_offd, num_nonzeros_offd); hypre_ParCSRBlockMatrixBlockSize(matrix) = block_size; hypre_ParCSRBlockMatrixGlobalNumRows(matrix) = global_num_rows; hypre_ParCSRBlockMatrixGlobalNumCols(matrix) = global_num_cols; hypre_ParCSRBlockMatrixFirstRowIndex(matrix) = first_row_index; hypre_ParCSRBlockMatrixFirstColDiag(matrix) = first_col_diag; hypre_ParCSRBlockMatrixLastRowIndex(matrix) = first_row_index + local_num_rows - 1; hypre_ParCSRBlockMatrixLastColDiag(matrix) = first_col_diag + local_num_cols - 1; hypre_ParCSRBlockMatrixColMapOffd(matrix) = NULL; hypre_ParCSRBlockMatrixAssumedPartition(matrix) = NULL; /* When NO_GLOBAL_PARTITION is set we could make these null, instead of leaving the range. If that change is made, then when this create is called from functions like the matrix-matrix multiply, be careful not to generate a new partition */ hypre_ParCSRBlockMatrixRowStarts(matrix) = row_starts; hypre_ParCSRBlockMatrixColStarts(matrix) = col_starts; hypre_ParCSRBlockMatrixCommPkg(matrix) = NULL; hypre_ParCSRBlockMatrixCommPkgT(matrix) = NULL; /* set defaults */ hypre_ParCSRBlockMatrixOwnsData(matrix) = 1; hypre_ParCSRBlockMatrixOwnsRowStarts(matrix) = 1; hypre_ParCSRBlockMatrixOwnsColStarts(matrix) = 1; if (row_starts == col_starts) hypre_ParCSRBlockMatrixOwnsColStarts(matrix) = 0; return matrix; }
HYPRE_Int hypre_BoomerAMGBlockCreateNodalA(hypre_ParCSRBlockMatrix *A, HYPRE_Int option, HYPRE_Int diag_option, hypre_ParCSRMatrix **AN_ptr) { MPI_Comm comm = hypre_ParCSRBlockMatrixComm(A); hypre_CSRBlockMatrix *A_diag = hypre_ParCSRBlockMatrixDiag(A); HYPRE_Int *A_diag_i = hypre_CSRBlockMatrixI(A_diag); HYPRE_Real *A_diag_data = hypre_CSRBlockMatrixData(A_diag); HYPRE_Int block_size = hypre_CSRBlockMatrixBlockSize(A_diag); HYPRE_Int bnnz = block_size*block_size; hypre_CSRBlockMatrix *A_offd = hypre_ParCSRMatrixOffd(A); HYPRE_Int *A_offd_i = hypre_CSRBlockMatrixI(A_offd); HYPRE_Real *A_offd_data = hypre_CSRBlockMatrixData(A_offd); HYPRE_Int *A_diag_j = hypre_CSRBlockMatrixJ(A_diag); HYPRE_Int *A_offd_j = hypre_CSRBlockMatrixJ(A_offd); HYPRE_Int *row_starts = hypre_ParCSRBlockMatrixRowStarts(A); HYPRE_Int *col_map_offd = hypre_ParCSRBlockMatrixColMapOffd(A); HYPRE_Int num_nonzeros_diag; HYPRE_Int num_nonzeros_offd = 0; HYPRE_Int num_cols_offd = 0; hypre_ParCSRMatrix *AN; hypre_CSRMatrix *AN_diag; HYPRE_Int *AN_diag_i; HYPRE_Int *AN_diag_j=NULL; HYPRE_Real *AN_diag_data = NULL; hypre_CSRMatrix *AN_offd; HYPRE_Int *AN_offd_i; HYPRE_Int *AN_offd_j = NULL; HYPRE_Real *AN_offd_data = NULL; HYPRE_Int *col_map_offd_AN = NULL; HYPRE_Int *row_starts_AN; hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRBlockMatrixCommPkg(A); HYPRE_Int num_sends; HYPRE_Int num_recvs; HYPRE_Int *send_procs; HYPRE_Int *send_map_starts; HYPRE_Int *send_map_elmts; HYPRE_Int *recv_procs; HYPRE_Int *recv_vec_starts; hypre_ParCSRCommPkg *comm_pkg_AN = NULL; HYPRE_Int *send_procs_AN = NULL; HYPRE_Int *send_map_starts_AN = NULL; HYPRE_Int *send_map_elmts_AN = NULL; HYPRE_Int *recv_procs_AN = NULL; HYPRE_Int *recv_vec_starts_AN = NULL; HYPRE_Int i; HYPRE_Int ierr = 0; HYPRE_Int num_procs; HYPRE_Int cnt; HYPRE_Int norm_type; HYPRE_Int global_num_nodes; HYPRE_Int num_nodes; HYPRE_Int index, k; HYPRE_Real tmp; HYPRE_Real sum; hypre_MPI_Comm_size(comm,&num_procs); if (!comm_pkg) { hypre_BlockMatvecCommPkgCreate(A); comm_pkg = hypre_ParCSRBlockMatrixCommPkg(A); } norm_type = fabs(option); /* Set up the new matrix AN */ #ifdef HYPRE_NO_GLOBAL_PARTITION row_starts_AN = hypre_CTAlloc(HYPRE_Int, 2); for (i=0; i < 2; i++) { row_starts_AN[i] = row_starts[i]; } #else row_starts_AN = hypre_CTAlloc(HYPRE_Int, num_procs+1); for (i=0; i < num_procs+1; i++) { row_starts_AN[i] = row_starts[i]; } #endif global_num_nodes = hypre_ParCSRBlockMatrixGlobalNumRows(A); num_nodes = hypre_CSRBlockMatrixNumRows(A_diag); /* the diag part */ num_nonzeros_diag = A_diag_i[num_nodes]; AN_diag_i = hypre_CTAlloc(HYPRE_Int, num_nodes+1); for (i=0; i <= num_nodes; i++) { AN_diag_i[i] = A_diag_i[i]; } AN_diag_j = hypre_CTAlloc(HYPRE_Int, num_nonzeros_diag); AN_diag_data = hypre_CTAlloc(HYPRE_Real, num_nonzeros_diag); AN_diag = hypre_CSRMatrixCreate(num_nodes, num_nodes, num_nonzeros_diag); hypre_CSRMatrixI(AN_diag) = AN_diag_i; hypre_CSRMatrixJ(AN_diag) = AN_diag_j; hypre_CSRMatrixData(AN_diag) = AN_diag_data; for (i=0; i< num_nonzeros_diag; i++) { AN_diag_j[i] = A_diag_j[i]; hypre_CSRBlockMatrixBlockNorm(norm_type, &A_diag_data[i*bnnz], &tmp, block_size); AN_diag_data[i] = tmp; } if (diag_option ==1 ) { /* make the diag entry the negative of the sum of off-diag entries (NEED * to get more below!)*/ /* the diagonal is the first element listed in each row - */ for (i=0; i < num_nodes; i++) { index = AN_diag_i[i]; sum = 0.0; for (k = AN_diag_i[i]+1; k < AN_diag_i[i+1]; k++) { sum += AN_diag_data[k]; } AN_diag_data[index] = -sum; } } else if (diag_option == 2) { /* make all diagonal entries negative */ /* the diagonal is the first element listed in each row - */ for (i=0; i < num_nodes; i++) { index = AN_diag_i[i]; AN_diag_data[index] = -AN_diag_data[index]; } } /* copy the commpkg */ if (comm_pkg) { comm_pkg_AN = hypre_CTAlloc(hypre_ParCSRCommPkg,1); hypre_ParCSRCommPkgComm(comm_pkg_AN) = comm; num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg); hypre_ParCSRCommPkgNumSends(comm_pkg_AN) = num_sends; num_recvs = hypre_ParCSRCommPkgNumRecvs(comm_pkg); hypre_ParCSRCommPkgNumRecvs(comm_pkg_AN) = num_recvs; send_procs = hypre_ParCSRCommPkgSendProcs(comm_pkg); send_map_starts = hypre_ParCSRCommPkgSendMapStarts(comm_pkg); send_map_elmts = hypre_ParCSRCommPkgSendMapElmts(comm_pkg); if (num_sends) { send_procs_AN = hypre_CTAlloc(HYPRE_Int, num_sends); send_map_elmts_AN = hypre_CTAlloc(HYPRE_Int, send_map_starts[num_sends]); } send_map_starts_AN = hypre_CTAlloc(HYPRE_Int, num_sends+1); send_map_starts_AN[0] = 0; for (i=0; i < num_sends; i++) { send_procs_AN[i] = send_procs[i]; send_map_starts_AN[i+1] = send_map_starts[i+1]; } cnt = send_map_starts_AN[num_sends]; for (i=0; i< cnt; i++) { send_map_elmts_AN[i] = send_map_elmts[i]; } hypre_ParCSRCommPkgSendProcs(comm_pkg_AN) = send_procs_AN; hypre_ParCSRCommPkgSendMapStarts(comm_pkg_AN) = send_map_starts_AN; hypre_ParCSRCommPkgSendMapElmts(comm_pkg_AN) = send_map_elmts_AN; recv_procs = hypre_ParCSRCommPkgRecvProcs(comm_pkg); recv_vec_starts = hypre_ParCSRCommPkgRecvVecStarts(comm_pkg); recv_vec_starts_AN = hypre_CTAlloc(HYPRE_Int, num_recvs+1); if (num_recvs) recv_procs_AN = hypre_CTAlloc(HYPRE_Int, num_recvs); recv_vec_starts_AN[0] = recv_vec_starts[0]; for (i=0; i < num_recvs; i++) { recv_procs_AN[i] = recv_procs[i]; recv_vec_starts_AN[i+1] = recv_vec_starts[i+1]; } hypre_ParCSRCommPkgRecvProcs(comm_pkg_AN) = recv_procs_AN; hypre_ParCSRCommPkgRecvVecStarts(comm_pkg_AN) = recv_vec_starts_AN; } /* the off-diag part */ num_cols_offd = hypre_CSRBlockMatrixNumCols(A_offd); col_map_offd_AN = hypre_CTAlloc(HYPRE_Int, num_cols_offd); for (i=0; i < num_cols_offd; i++) { col_map_offd_AN[i] = col_map_offd[i]; } num_nonzeros_offd = A_offd_i[num_nodes]; AN_offd_i = hypre_CTAlloc(HYPRE_Int, num_nodes+1); for (i=0; i <= num_nodes; i++) { AN_offd_i[i] = A_offd_i[i]; } AN_offd_j = hypre_CTAlloc(HYPRE_Int, num_nonzeros_offd); AN_offd_data = hypre_CTAlloc(HYPRE_Real, num_nonzeros_offd); for (i=0; i< num_nonzeros_offd; i++) { AN_offd_j[i] = A_offd_j[i]; hypre_CSRBlockMatrixBlockNorm(norm_type, &A_offd_data[i*bnnz], &tmp, block_size); AN_offd_data[i] = tmp; } AN_offd = hypre_CSRMatrixCreate(num_nodes, num_cols_offd, num_nonzeros_offd); hypre_CSRMatrixI(AN_offd) = AN_offd_i; hypre_CSRMatrixJ(AN_offd) = AN_offd_j; hypre_CSRMatrixData(AN_offd) = AN_offd_data; if (diag_option ==1 ) { /* make the diag entry the negative of the sum of off-diag entries (here we are adding the off_diag contribution)*/ /* the diagonal is the first element listed in each row of AN_diag_data - */ for (i=0; i < num_nodes; i++) { sum = 0.0; for (k = AN_offd_i[i]; k < AN_offd_i[i+1]; k++) { sum += AN_offd_data[k]; } index = AN_diag_i[i];/* location of diag entry in data */ AN_diag_data[index] -= sum; /* subtract from current value */ } } /* now create AN */ AN = hypre_ParCSRMatrixCreate(comm, global_num_nodes, global_num_nodes, row_starts_AN, row_starts_AN, num_cols_offd, num_nonzeros_diag, num_nonzeros_offd); /* we already created the diag and offd matrices - so we don't need the ones created above */ hypre_CSRMatrixDestroy(hypre_ParCSRMatrixDiag(AN)); hypre_CSRMatrixDestroy(hypre_ParCSRMatrixOffd(AN)); hypre_ParCSRMatrixDiag(AN) = AN_diag; hypre_ParCSRMatrixOffd(AN) = AN_offd; hypre_ParCSRMatrixColMapOffd(AN) = col_map_offd_AN; hypre_ParCSRMatrixCommPkg(AN) = comm_pkg_AN; *AN_ptr = AN; return (ierr); }