12 #include "../config/config.hpp"
35 void hypre_CSRMatrixEliminateAXB(hypre_CSRMatrix *A,
36 HYPRE_Int nrows_to_eliminate,
37 HYPRE_Int *rows_to_eliminate,
42 HYPRE_Int irow, jcol, ibeg, iend, pos;
45 HYPRE_Int *Ai = hypre_CSRMatrixI(A);
46 HYPRE_Int *Aj = hypre_CSRMatrixJ(A);
47 HYPRE_Real *Adata = hypre_CSRMatrixData(A);
48 HYPRE_Int nrows = hypre_CSRMatrixNumRows(A);
50 HYPRE_Real *Xdata = hypre_VectorData(X);
51 HYPRE_Real *Bdata = hypre_VectorData(B);
54 for (i = 0; i < nrows; i++)
58 for (j = ibeg; j < iend; j++)
61 pos = hypre_BinarySearch(rows_to_eliminate, jcol, nrows_to_eliminate);
66 Bdata[i] -= a * Xdata[jcol];
72 for (i = 0; i < nrows_to_eliminate; i++)
74 irow = rows_to_eliminate[i];
77 for (j = ibeg; j < iend; j++)
96 void hypre_CSRMatrixEliminateOffdColsAXB(hypre_CSRMatrix *A,
97 HYPRE_Int ncols_to_eliminate,
98 HYPRE_Int *eliminate_cols,
99 HYPRE_Real *eliminate_coefs,
103 HYPRE_Int ibeg, iend, pos;
106 HYPRE_Int *Ai = hypre_CSRMatrixI(A);
107 HYPRE_Int *Aj = hypre_CSRMatrixJ(A);
108 HYPRE_Real *Adata = hypre_CSRMatrixData(A);
109 HYPRE_Int nrows = hypre_CSRMatrixNumRows(A);
111 HYPRE_Real *Bdata = hypre_VectorData(B);
113 for (i = 0; i < nrows; i++)
117 for (j = ibeg; j < iend; j++)
119 pos = hypre_BinarySearch(eliminate_cols, Aj[j], ncols_to_eliminate);
124 Bdata[i] -= a * eliminate_coefs[pos];
135 void hypre_CSRMatrixEliminateOffdRowsAXB(hypre_CSRMatrix *A,
136 HYPRE_Int nrows_to_eliminate,
137 HYPRE_Int *rows_to_eliminate)
139 HYPRE_Int *Ai = hypre_CSRMatrixI(A);
140 HYPRE_Real *Adata = hypre_CSRMatrixData(A);
143 HYPRE_Int irow, ibeg, iend;
145 for (i = 0; i < nrows_to_eliminate; i++)
147 irow = rows_to_eliminate[i];
150 for (j = ibeg; j < iend; j++)
181 void hypre_ParCSRMatrixEliminateAXB(hypre_ParCSRMatrix *A,
182 HYPRE_Int num_rowscols_to_elim,
183 HYPRE_Int *rowscols_to_elim,
187 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
188 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
189 HYPRE_Int diag_nrows = hypre_CSRMatrixNumRows(diag);
190 HYPRE_Int offd_ncols = hypre_CSRMatrixNumCols(offd);
192 hypre_Vector *Xlocal = hypre_ParVectorLocalVector(X);
193 hypre_Vector *Blocal = hypre_ParVectorLocalVector(B);
195 HYPRE_Real *Bdata = hypre_VectorData(Blocal);
196 HYPRE_Real *Xdata = hypre_VectorData(Xlocal);
198 HYPRE_Int num_offd_cols_to_elim;
199 HYPRE_Int *offd_cols_to_elim;
200 HYPRE_Real *eliminate_coefs;
203 hypre_ParCSRCommHandle *comm_handle;
204 hypre_ParCSRCommPkg *comm_pkg;
206 HYPRE_Int index, start;
207 HYPRE_Int i, j, k, irow;
209 HYPRE_Real *eliminate_row = hypre_CTAlloc(HYPRE_Real, diag_nrows);
210 HYPRE_Real *eliminate_col = hypre_CTAlloc(HYPRE_Real, offd_ncols);
211 HYPRE_Real *buf_data, coef;
214 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
217 hypre_MatvecCommPkgCreate(A);
218 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
224 for (i = 0; i < diag_nrows; i++)
226 eliminate_row[i] = std::numeric_limits<HYPRE_Real>::quiet_NaN();
228 for (i = 0; i < num_rowscols_to_elim; i++)
230 irow = rowscols_to_elim[i];
231 eliminate_row[irow] = Xdata[irow];
236 num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
237 buf_data = hypre_CTAlloc(HYPRE_Real,
238 hypre_ParCSRCommPkgSendMapStart(comm_pkg,
241 for (i = 0; i < num_sends; i++)
243 start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
244 for (j = start; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++)
246 k = hypre_ParCSRCommPkgSendMapElmt(comm_pkg,j);
247 buf_data[index++] = eliminate_row[k];
250 comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg,
251 buf_data, eliminate_col);
254 hypre_CSRMatrixEliminateAXB(diag, num_rowscols_to_elim, rowscols_to_elim,
258 hypre_ParCSRCommHandleDestroy(comm_handle);
261 num_offd_cols_to_elim = 0;
262 for (i = 0; i < offd_ncols; i++)
264 coef = eliminate_col[i];
267 num_offd_cols_to_elim++;
271 offd_cols_to_elim = hypre_CTAlloc(HYPRE_Int, num_offd_cols_to_elim);
272 eliminate_coefs = hypre_CTAlloc(HYPRE_Real, num_offd_cols_to_elim);
275 num_offd_cols_to_elim = 0;
276 for (i = 0; i < offd_ncols; i++)
278 coef = eliminate_col[i];
281 offd_cols_to_elim[num_offd_cols_to_elim] = i;
282 eliminate_coefs[num_offd_cols_to_elim] = coef;
283 num_offd_cols_to_elim++;
287 hypre_TFree(buf_data);
288 hypre_TFree(eliminate_row);
289 hypre_TFree(eliminate_col);
292 hypre_CSRMatrixEliminateOffdColsAXB(offd, num_offd_cols_to_elim,
294 eliminate_coefs, Blocal);
296 hypre_CSRMatrixEliminateOffdRowsAXB(offd, num_rowscols_to_elim,
300 for (
int i = 0; i < num_rowscols_to_elim; i++)
302 irow = rowscols_to_elim[i];
303 Bdata[irow] = Xdata[irow];
306 hypre_TFree(offd_cols_to_elim);
307 hypre_TFree(eliminate_coefs);
320 void hypre_CSRMatrixElimCreate(hypre_CSRMatrix *A,
322 HYPRE_Int nrows, HYPRE_Int *rows,
323 HYPRE_Int ncols, HYPRE_Int *cols,
327 HYPRE_Int A_beg, A_end;
329 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
330 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
331 HYPRE_Int A_rows = hypre_CSRMatrixNumRows(A);
333 hypre_CSRMatrixI(Ae) = hypre_TAlloc(HYPRE_Int, A_rows+1);
335 HYPRE_Int *Ae_i = hypre_CSRMatrixI(Ae);
338 for (i = 0; i < A_rows; i++)
345 if (hypre_BinarySearch(rows, i, nrows) >= 0)
348 nnz += A_end - A_beg;
352 for (j = A_beg; j < A_end; j++)
354 col_mark[A_j[j]] = 1;
361 for (j = A_beg; j < A_end; j++)
364 if (hypre_BinarySearch(cols, col, ncols) >= 0)
367 if (col_mark) { col_mark[col] = 1; }
374 hypre_CSRMatrixJ(Ae) = hypre_TAlloc(HYPRE_Int, nnz);
375 hypre_CSRMatrixData(Ae) = hypre_TAlloc(HYPRE_Real, nnz);
376 hypre_CSRMatrixNumNonzeros(Ae) = nnz;
386 void hypre_CSRMatrixEliminateRowsCols(hypre_CSRMatrix *A,
388 HYPRE_Int nrows, HYPRE_Int *rows,
389 HYPRE_Int ncols, HYPRE_Int *cols,
390 int diag, HYPRE_Int* col_remap)
392 HYPRE_Int i, j, k, col;
393 HYPRE_Int A_beg, Ae_beg, A_end;
396 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
397 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
398 HYPRE_Real *A_data = hypre_CSRMatrixData(A);
399 HYPRE_Int A_rows = hypre_CSRMatrixNumRows(A);
401 HYPRE_Int *Ae_i = hypre_CSRMatrixI(Ae);
402 HYPRE_Int *Ae_j = hypre_CSRMatrixJ(Ae);
403 HYPRE_Real *Ae_data = hypre_CSRMatrixData(Ae);
405 for (i = 0; i < A_rows; i++)
411 if (hypre_BinarySearch(rows, i, nrows) >= 0)
414 for (j = A_beg, k = Ae_beg; j < A_end; j++, k++)
417 Ae_j[k] = col_remap ? col_remap[col] : col;
418 a = (diag && col == i) ? 1.0 : 0.0;
419 Ae_data[k] = A_data[j] - a;
426 for (j = A_beg, k = Ae_beg; j < A_end; j++)
429 if (hypre_BinarySearch(cols, col, ncols) >= 0)
431 Ae_j[k] = col_remap ? col_remap[col] : col;
432 Ae_data[k] = A_data[j];
457 void hypre_ParCSRMatrixEliminateAAe(hypre_ParCSRMatrix *A,
458 hypre_ParCSRMatrix **Ae,
459 HYPRE_Int num_rowscols_to_elim,
460 HYPRE_Int *rowscols_to_elim)
464 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
465 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
466 HYPRE_Int A_diag_nrows = hypre_CSRMatrixNumRows(A_diag);
467 HYPRE_Int A_offd_ncols = hypre_CSRMatrixNumCols(A_offd);
469 *Ae = hypre_ParCSRMatrixCreate(hypre_ParCSRMatrixComm(A),
470 hypre_ParCSRMatrixGlobalNumRows(A),
471 hypre_ParCSRMatrixGlobalNumCols(A),
472 hypre_ParCSRMatrixRowStarts(A),
473 hypre_ParCSRMatrixColStarts(A),
476 hypre_ParCSRMatrixSetRowStartsOwner(*Ae, 0);
477 hypre_ParCSRMatrixSetColStartsOwner(*Ae, 0);
479 hypre_CSRMatrix *Ae_diag = hypre_ParCSRMatrixDiag(*Ae);
480 hypre_CSRMatrix *Ae_offd = hypre_ParCSRMatrixOffd(*Ae);
481 HYPRE_Int Ae_offd_ncols;
483 HYPRE_Int num_offd_cols_to_elim;
484 HYPRE_Int *offd_cols_to_elim;
486 HYPRE_Int *A_col_map_offd = hypre_ParCSRMatrixColMapOffd(A);
487 HYPRE_Int *Ae_col_map_offd;
490 HYPRE_Int *col_remap;
494 hypre_ParCSRCommHandle *comm_handle;
495 hypre_ParCSRCommPkg *comm_pkg;
496 HYPRE_Int num_sends, *int_buf_data;
497 HYPRE_Int index, start;
499 HYPRE_Int *eliminate_row = hypre_CTAlloc(HYPRE_Int, A_diag_nrows);
500 HYPRE_Int *eliminate_col = hypre_CTAlloc(HYPRE_Int, A_offd_ncols);
503 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
506 hypre_MatvecCommPkgCreate(A);
507 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
511 for (i = 0; i < A_diag_nrows; i++)
513 eliminate_row[i] = 0;
515 for (i = 0; i < num_rowscols_to_elim; i++)
517 eliminate_row[rowscols_to_elim[i]] = 1;
522 num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
523 int_buf_data = hypre_CTAlloc(HYPRE_Int,
524 hypre_ParCSRCommPkgSendMapStart(comm_pkg,
527 for (i = 0; i < num_sends; i++)
529 start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
530 for (j = start; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++)
532 k = hypre_ParCSRCommPkgSendMapElmt(comm_pkg, j);
533 int_buf_data[index++] = eliminate_row[k];
536 comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg,
537 int_buf_data, eliminate_col);
540 hypre_CSRMatrixElimCreate(A_diag, Ae_diag,
541 num_rowscols_to_elim, rowscols_to_elim,
542 num_rowscols_to_elim, rowscols_to_elim,
545 hypre_CSRMatrixEliminateRowsCols(A_diag, Ae_diag,
546 num_rowscols_to_elim, rowscols_to_elim,
547 num_rowscols_to_elim, rowscols_to_elim,
549 hypre_CSRMatrixReorder(Ae_diag);
552 hypre_ParCSRCommHandleDestroy(comm_handle);
555 num_offd_cols_to_elim = 0;
556 for (i = 0; i < A_offd_ncols; i++)
558 if (eliminate_col[i]) { num_offd_cols_to_elim++; }
561 offd_cols_to_elim = hypre_CTAlloc(HYPRE_Int, num_offd_cols_to_elim);
564 num_offd_cols_to_elim = 0;
565 for (i = 0; i < A_offd_ncols; i++)
567 if (eliminate_col[i])
569 offd_cols_to_elim[num_offd_cols_to_elim++] = i;
573 hypre_TFree(int_buf_data);
574 hypre_TFree(eliminate_row);
575 hypre_TFree(eliminate_col);
579 col_mark = hypre_CTAlloc(HYPRE_Int, A_offd_ncols);
580 col_remap = hypre_CTAlloc(HYPRE_Int, A_offd_ncols);
582 hypre_CSRMatrixElimCreate(A_offd, Ae_offd,
583 num_rowscols_to_elim, rowscols_to_elim,
584 num_offd_cols_to_elim, offd_cols_to_elim,
587 for (i = k = 0; i < A_offd_ncols; i++)
589 if (col_mark[i]) { col_remap[i] = k++; }
592 hypre_CSRMatrixEliminateRowsCols(A_offd, Ae_offd,
593 num_rowscols_to_elim, rowscols_to_elim,
594 num_offd_cols_to_elim, offd_cols_to_elim,
599 for (i = 0; i < A_offd_ncols; i++)
601 if (col_mark[i]) { Ae_offd_ncols++; }
604 Ae_col_map_offd = hypre_CTAlloc(HYPRE_Int, Ae_offd_ncols);
607 for (i = 0; i < A_offd_ncols; i++)
611 Ae_col_map_offd[Ae_offd_ncols++] = A_col_map_offd[i];
615 hypre_ParCSRMatrixColMapOffd(*Ae) = Ae_col_map_offd;
616 hypre_CSRMatrixNumCols(Ae_offd) = Ae_offd_ncols;
618 hypre_TFree(col_remap);
619 hypre_TFree(col_mark);
620 hypre_TFree(offd_cols_to_elim);
622 hypre_ParCSRMatrixSetNumNonzeros(*Ae);
623 hypre_MatvecCommPkgCreate(*Ae);
631 void hypre_CSRMatrixSplit(hypre_CSRMatrix *A,
632 HYPRE_Int nr, HYPRE_Int nc,
633 HYPRE_Int *row_block_num, HYPRE_Int *col_block_num,
634 hypre_CSRMatrix **blocks)
636 HYPRE_Int i, j, k, bi, bj;
638 HYPRE_Int* A_i = hypre_CSRMatrixI(A);
639 HYPRE_Int* A_j = hypre_CSRMatrixJ(A);
640 HYPRE_Complex* A_data = hypre_CSRMatrixData(A);
642 HYPRE_Int A_rows = hypre_CSRMatrixNumRows(A);
643 HYPRE_Int A_cols = hypre_CSRMatrixNumCols(A);
645 HYPRE_Int *num_rows = hypre_CTAlloc(HYPRE_Int, nr);
646 HYPRE_Int *num_cols = hypre_CTAlloc(HYPRE_Int, nc);
648 HYPRE_Int *block_row = hypre_TAlloc(HYPRE_Int, A_rows);
649 HYPRE_Int *block_col = hypre_TAlloc(HYPRE_Int, A_cols);
651 for (i = 0; i < A_rows; i++)
653 block_row[i] = num_rows[row_block_num[i]]++;
655 for (j = 0; j < A_cols; j++)
657 block_col[j] = num_cols[col_block_num[j]]++;
661 for (i = 0; i < nr; i++)
663 for (j = 0; j < nc; j++)
665 hypre_CSRMatrix *B = hypre_CSRMatrixCreate(num_rows[i], num_cols[j], 0);
666 hypre_CSRMatrixI(B) = hypre_CTAlloc(HYPRE_Int, num_rows[i] + 1);
667 blocks[i*nc + j] = B;
672 for (i = 0; i < A_rows; i++)
674 bi = row_block_num[i];
675 for (j = A_i[i]; j < A_i[i+1]; j++)
677 bj = col_block_num[A_j[j]];
678 hypre_CSRMatrix *B = blocks[bi*nc + bj];
679 hypre_CSRMatrixI(B)[block_row[i] + 1]++;
684 for (k = 0; k < nr*nc; k++)
686 hypre_CSRMatrix *B = blocks[k];
687 HYPRE_Int* B_i = hypre_CSRMatrixI(B);
689 HYPRE_Int nnz = 0, rs;
690 for (
int k = 1; k <= hypre_CSRMatrixNumRows(B); k++)
692 rs = B_i[k], B_i[k] = nnz, nnz += rs;
695 hypre_CSRMatrixJ(B) = hypre_TAlloc(HYPRE_Int, nnz);
696 hypre_CSRMatrixData(B) = hypre_TAlloc(HYPRE_Complex, nnz);
697 hypre_CSRMatrixNumNonzeros(B) = nnz;
701 for (i = 0; i < A_rows; i++)
703 bi = row_block_num[i];
704 for (j = A_i[i]; j < A_i[i+1]; j++)
707 bj = col_block_num[k];
708 hypre_CSRMatrix *B = blocks[bi*nc + bj];
709 HYPRE_Int *bii = hypre_CSRMatrixI(B) + block_row[i] + 1;
710 hypre_CSRMatrixJ(B)[*bii] = block_col[k];
711 hypre_CSRMatrixData(B)[*bii] = A_data[j];
716 hypre_TFree(block_col);
717 hypre_TFree(block_row);
719 hypre_TFree(num_cols);
720 hypre_TFree(num_rows);
724 void hypre_ParCSRMatrixSplit(hypre_ParCSRMatrix *A,
725 HYPRE_Int nr, HYPRE_Int nc,
726 hypre_ParCSRMatrix **blocks,
727 int interleaved_rows,
int interleaved_cols)
731 MPI_Comm comm = hypre_ParCSRMatrixComm(A);
733 hypre_CSRMatrix *Adiag = hypre_ParCSRMatrixDiag(A);
734 hypre_CSRMatrix *Aoffd = hypre_ParCSRMatrixOffd(A);
736 HYPRE_Int global_rows = hypre_ParCSRMatrixGlobalNumRows(A);
737 HYPRE_Int global_cols = hypre_ParCSRMatrixGlobalNumCols(A);
739 HYPRE_Int local_rows = hypre_CSRMatrixNumRows(Adiag);
740 HYPRE_Int local_cols = hypre_CSRMatrixNumCols(Adiag);
741 HYPRE_Int offd_cols = hypre_CSRMatrixNumCols(Aoffd);
743 hypre_assert(local_rows % nr == 0 && local_cols % nc == 0);
744 hypre_assert(global_rows % nr == 0 && global_cols % nc == 0);
746 HYPRE_Int block_rows = local_rows / nr;
747 HYPRE_Int block_cols = local_cols / nc;
748 HYPRE_Int num_blocks = nr * nc;
751 HYPRE_Int *row_block_num = hypre_TAlloc(HYPRE_Int, local_rows);
752 HYPRE_Int *col_block_num = hypre_TAlloc(HYPRE_Int, local_cols);
754 for (i = 0; i < local_rows; i++)
756 row_block_num[i] = interleaved_rows ? (i % nr) : (i / block_rows);
758 for (i = 0; i < local_cols; i++)
760 col_block_num[i] = interleaved_cols ? (i % nc) : (i / block_cols);
764 HYPRE_Int* offd_col_block_num = hypre_TAlloc(HYPRE_Int, offd_cols);
765 hypre_ParCSRCommHandle *comm_handle;
766 HYPRE_Int *int_buf_data;
769 hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg(A);
772 hypre_MatvecCommPkgCreate(A);
773 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
777 HYPRE_Int *count = hypre_CTAlloc(HYPRE_Int, nc);
778 HYPRE_Int *block_global_col = hypre_TAlloc(HYPRE_Int, local_cols);
779 HYPRE_Int first_col = hypre_ParCSRMatrixFirstColDiag(A) / nc;
780 for (i = 0; i < local_cols; i++)
782 block_global_col[i] = first_col + count[col_block_num[i]]++;
787 HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
788 int_buf_data = hypre_CTAlloc(HYPRE_Int,
789 hypre_ParCSRCommPkgSendMapStart(comm_pkg,
791 HYPRE_Int start, index = 0;
792 for (i = 0; i < num_sends; i++)
794 start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
795 for (j = start; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++)
797 k = hypre_ParCSRCommPkgSendMapElmt(comm_pkg, j);
798 int_buf_data[index++] = col_block_num[k] + nc*block_global_col[k];
801 hypre_TFree(block_global_col);
803 comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data,
808 HYPRE_Int num_procs = 1;
809 if (!hypre_ParCSRMatrixAssumedPartition(A))
811 hypre_MPI_Comm_size(comm, &num_procs);
814 HYPRE_Int *row_starts = hypre_TAlloc(HYPRE_Int, num_procs+1);
815 HYPRE_Int *col_starts = hypre_TAlloc(HYPRE_Int, num_procs+1);
816 for (i = 0; i <= num_procs; i++)
818 row_starts[i] = hypre_ParCSRMatrixRowStarts(A)[i] / nr;
819 col_starts[i] = hypre_ParCSRMatrixColStarts(A)[i] / nc;
822 for (i = 0; i < num_blocks; i++)
824 blocks[i] = hypre_ParCSRMatrixCreate(comm,
825 global_rows/nr, global_cols/nc,
826 row_starts, col_starts, 0, 0, 0);
830 hypre_CSRMatrix **csr_blocks = hypre_TAlloc(hypre_CSRMatrix*, nr*nc);
831 hypre_CSRMatrixSplit(Adiag, nr, nc, row_block_num, col_block_num,
834 for (i = 0; i < num_blocks; i++)
836 hypre_TFree(hypre_ParCSRMatrixDiag(blocks[i]));
837 hypre_ParCSRMatrixDiag(blocks[i]) = csr_blocks[i];
841 hypre_ParCSRCommHandleDestroy(comm_handle);
842 hypre_TFree(int_buf_data);
845 HYPRE_Int* offd_global_col = hypre_TAlloc(HYPRE_Int, offd_cols);
846 for (i = 0; i < offd_cols; i++)
848 offd_global_col[i] = offd_col_block_num[i] / nc;
849 offd_col_block_num[i] %= nc;
853 hypre_CSRMatrixSplit(Aoffd, nr, nc, row_block_num, offd_col_block_num,
856 for (i = 0; i < num_blocks; i++)
858 hypre_TFree(hypre_ParCSRMatrixOffd(blocks[i]));
859 hypre_ParCSRMatrixOffd(blocks[i]) = csr_blocks[i];
862 hypre_TFree(csr_blocks);
863 hypre_TFree(col_block_num);
864 hypre_TFree(row_block_num);
867 for (
int bi = 0; bi < nr; bi++)
869 for (
int bj = 0; bj < nc; bj++)
871 hypre_ParCSRMatrix *block = blocks[bi*nc + bj];
872 hypre_CSRMatrix *block_offd = hypre_ParCSRMatrixOffd(block);
873 HYPRE_Int block_offd_cols = hypre_CSRMatrixNumCols(block_offd);
875 HYPRE_Int *block_col_map = hypre_TAlloc(HYPRE_Int, block_offd_cols);
876 for (i = j = 0; i < offd_cols; i++)
878 HYPRE_Int bn = offd_col_block_num[i];
879 if (bn == bj) { block_col_map[j++] = offd_global_col[i]; }
881 hypre_assert(j == block_offd_cols);
883 hypre_ParCSRMatrixColMapOffd(block) = block_col_map;
887 hypre_TFree(offd_global_col);
888 hypre_TFree(offd_col_block_num);
891 for (i = 0; i < num_blocks; i++)
893 hypre_ParCSRMatrixSetNumNonzeros(blocks[i]);
894 hypre_MatvecCommPkgCreate(blocks[i]);
896 hypre_ParCSRMatrixOwnsData(blocks[i]) = 1;
899 hypre_ParCSRMatrixOwnsRowStarts(blocks[i]) = !i;
900 hypre_ParCSRMatrixOwnsColStarts(blocks[i]) = !i;
905 void hypre_CSRMatrixBooleanMatvec(hypre_CSRMatrix *A,
912 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
913 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
914 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A);
916 HYPRE_Int *A_rownnz = hypre_CSRMatrixRownnz(A);
917 HYPRE_Int num_rownnz = hypre_CSRMatrixNumRownnz(A);
919 HYPRE_Bool *x_data = x;
920 HYPRE_Bool *y_data = y;
922 HYPRE_Bool temp, tempx;
936 #ifdef HYPRE_USING_OPENMP
937 #pragma omp parallel for private(i) HYPRE_SMP_SCHEDULE
939 for (i = 0; i < num_rows; i++)
941 y_data[i] = y_data[i] && beta;
952 #ifdef HYPRE_USING_OPENMP
953 #pragma omp parallel for private(i) HYPRE_SMP_SCHEDULE
955 for (i = 0; i < num_rows; i++)
971 if (num_rownnz < xpar*(num_rows))
973 #ifdef HYPRE_USING_OPENMP
974 #pragma omp parallel for private(i,jj,m,tempx) HYPRE_SMP_SCHEDULE
976 for (i = 0; i < num_rownnz; i++)
981 for (jj = A_i[m]; jj < A_i[m+1]; jj++)
984 tempx = tempx || x_data[A_j[jj]];
986 y_data[m] = y_data[m] || tempx;
991 #ifdef HYPRE_USING_OPENMP
992 #pragma omp parallel for private(i,jj,temp) HYPRE_SMP_SCHEDULE
994 for (i = 0; i < num_rows; i++)
997 for (jj = A_i[i]; jj < A_i[i+1]; jj++)
1000 temp = temp || x_data[A_j[jj]];
1002 y_data[i] = y_data[i] || temp;
1014 hypre_ParCSRCommHandle *
1015 hypre_ParCSRCommHandleCreate_bool(HYPRE_Int job,
1016 hypre_ParCSRCommPkg *comm_pkg,
1017 HYPRE_Bool *send_data,
1018 HYPRE_Bool *recv_data)
1020 HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
1021 HYPRE_Int num_recvs = hypre_ParCSRCommPkgNumRecvs(comm_pkg);
1022 MPI_Comm comm = hypre_ParCSRCommPkgComm(comm_pkg);
1024 hypre_ParCSRCommHandle *comm_handle;
1025 HYPRE_Int num_requests;
1026 hypre_MPI_Request *requests;
1029 HYPRE_Int my_id, num_procs;
1030 HYPRE_Int ip, vec_start, vec_len;
1032 num_requests = num_sends + num_recvs;
1033 requests = hypre_CTAlloc(hypre_MPI_Request, num_requests);
1035 hypre_MPI_Comm_size(comm, &num_procs);
1036 hypre_MPI_Comm_rank(comm, &my_id);
1043 HYPRE_Bool *d_send_data = (HYPRE_Bool *) send_data;
1044 HYPRE_Bool *d_recv_data = (HYPRE_Bool *) recv_data;
1045 for (i = 0; i < num_recvs; i++)
1047 ip = hypre_ParCSRCommPkgRecvProc(comm_pkg, i);
1048 vec_start = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i);
1049 vec_len = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i+1)-vec_start;
1050 hypre_MPI_Irecv(&d_recv_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1051 ip, 0, comm, &requests[j++]);
1053 for (i = 0; i < num_sends; i++)
1055 vec_start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
1056 vec_len = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1)-vec_start;
1057 ip = hypre_ParCSRCommPkgSendProc(comm_pkg, i);
1058 hypre_MPI_Isend(&d_send_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1059 ip, 0, comm, &requests[j++]);
1065 HYPRE_Bool *d_send_data = (HYPRE_Bool *) send_data;
1066 HYPRE_Bool *d_recv_data = (HYPRE_Bool *) recv_data;
1067 for (i = 0; i < num_sends; i++)
1069 vec_start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
1070 vec_len = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1)-vec_start;
1071 ip = hypre_ParCSRCommPkgSendProc(comm_pkg, i);
1072 hypre_MPI_Irecv(&d_recv_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1073 ip, 0, comm, &requests[j++]);
1075 for (i = 0; i < num_recvs; i++)
1077 ip = hypre_ParCSRCommPkgRecvProc(comm_pkg, i);
1078 vec_start = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i);
1079 vec_len = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i+1)-vec_start;
1080 hypre_MPI_Isend(&d_send_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1081 ip, 0, comm, &requests[j++]);
1090 comm_handle = hypre_CTAlloc(hypre_ParCSRCommHandle, 1);
1092 hypre_ParCSRCommHandleCommPkg(comm_handle) = comm_pkg;
1093 hypre_ParCSRCommHandleSendData(comm_handle) = send_data;
1094 hypre_ParCSRCommHandleRecvData(comm_handle) = recv_data;
1095 hypre_ParCSRCommHandleNumRequests(comm_handle) = num_requests;
1096 hypre_ParCSRCommHandleRequests(comm_handle) = requests;
1102 void hypre_ParCSRMatrixBooleanMatvec(hypre_ParCSRMatrix *A,
1108 hypre_ParCSRCommHandle *comm_handle;
1109 hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg(A);
1110 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
1111 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
1113 HYPRE_Int num_cols_offd = hypre_CSRMatrixNumCols(offd);
1114 HYPRE_Int num_sends, i, j, index;
1116 HYPRE_Bool *x_tmp, *x_buf;
1118 x_tmp = hypre_CTAlloc(HYPRE_Bool, num_cols_offd);
1126 hypre_MatvecCommPkgCreate(A);
1127 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
1130 num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
1131 x_buf = hypre_CTAlloc(HYPRE_Bool,
1132 hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends));
1135 for (i = 0; i < num_sends; i++)
1137 j = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
1138 for ( ; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++)
1140 x_buf[index++] = x[hypre_ParCSRCommPkgSendMapElmt(comm_pkg, j)];
1144 comm_handle = hypre_ParCSRCommHandleCreate_bool(1, comm_pkg, x_buf, x_tmp);
1146 hypre_CSRMatrixBooleanMatvec(diag, alpha, x, beta, y);
1148 hypre_ParCSRCommHandleDestroy(comm_handle);
1152 hypre_CSRMatrixBooleanMatvec(offd, alpha, x_tmp, 1, y);
1160 hypre_CSRMatrixSum(hypre_CSRMatrix *A,
1164 HYPRE_Complex *A_data = hypre_CSRMatrixData(A);
1165 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
1166 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
1167 HYPRE_Int nrows_A = hypre_CSRMatrixNumRows(A);
1168 HYPRE_Int ncols_A = hypre_CSRMatrixNumCols(A);
1169 HYPRE_Complex *B_data = hypre_CSRMatrixData(B);
1170 HYPRE_Int *B_i = hypre_CSRMatrixI(B);
1171 HYPRE_Int *B_j = hypre_CSRMatrixJ(B);
1172 HYPRE_Int nrows_B = hypre_CSRMatrixNumRows(B);
1173 HYPRE_Int ncols_B = hypre_CSRMatrixNumCols(B);
1175 HYPRE_Int ia, j, pos;
1178 if (nrows_A != nrows_B || ncols_A != ncols_B)
1183 marker = hypre_CTAlloc(HYPRE_Int, ncols_A);
1184 for (ia = 0; ia < ncols_A; ia++)
1189 for (ia = 0; ia < nrows_A; ia++)
1191 for (j = A_i[ia]; j < A_i[ia+1]; j++)
1196 for (j = B_i[ia]; j < B_i[ia+1]; j++)
1198 pos = marker[B_j[j]];
1203 A_data[pos] += beta * B_data[j];
1207 hypre_TFree(marker);
1211 hypre_ParCSRMatrix *
1212 hypre_ParCSRMatrixAdd(hypre_ParCSRMatrix *A,
1213 hypre_ParCSRMatrix *B)
1215 MPI_Comm comm = hypre_ParCSRMatrixComm(A);
1216 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
1217 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
1218 HYPRE_Int *A_cmap = hypre_ParCSRMatrixColMapOffd(A);
1219 HYPRE_Int A_cmap_size = hypre_CSRMatrixNumCols(A_offd);
1220 hypre_CSRMatrix *B_diag = hypre_ParCSRMatrixDiag(B);
1221 hypre_CSRMatrix *B_offd = hypre_ParCSRMatrixOffd(B);
1222 HYPRE_Int *B_cmap = hypre_ParCSRMatrixColMapOffd(B);
1223 HYPRE_Int B_cmap_size = hypre_CSRMatrixNumCols(B_offd);
1224 hypre_ParCSRMatrix *C;
1225 hypre_CSRMatrix *C_diag;
1226 hypre_CSRMatrix *C_offd;
1231 if (A_cmap_size != B_cmap_size)
1235 for (im = 0; im < A_cmap_size; im++)
1237 if (A_cmap[im] != B_cmap[im])
1244 C_diag = hypre_CSRMatrixAdd(A_diag, B_diag);
1249 C_offd = hypre_CSRMatrixAdd(A_offd, B_offd);
1252 hypre_CSRMatrixDestroy(C_diag);
1256 C_cmap = hypre_TAlloc(HYPRE_Int, A_cmap_size);
1257 for (im = 0; im < A_cmap_size; im++)
1259 C_cmap[im] = A_cmap[im];
1262 C = hypre_ParCSRMatrixCreate(comm,
1263 hypre_ParCSRMatrixGlobalNumRows(A),
1264 hypre_ParCSRMatrixGlobalNumCols(A),
1265 hypre_ParCSRMatrixRowStarts(A),
1266 hypre_ParCSRMatrixColStarts(A),
1267 hypre_CSRMatrixNumCols(C_offd),
1268 hypre_CSRMatrixNumNonzeros(C_diag),
1269 hypre_CSRMatrixNumNonzeros(C_offd));
1273 hypre_CSRMatrixDestroy(hypre_ParCSRMatrixDiag(C));
1274 hypre_CSRMatrixDestroy(hypre_ParCSRMatrixOffd(C));
1275 hypre_ParCSRMatrixDiag(C) = C_diag;
1276 hypre_ParCSRMatrixOffd(C) = C_offd;
1278 hypre_ParCSRMatrixColMapOffd(C) = C_cmap;
1283 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(C));
1286 hypre_ParCSRMatrixSetDataOwner(C, 1);
1288 hypre_ParCSRMatrixSetRowStartsOwner(C, 0);
1289 hypre_ParCSRMatrixSetColStartsOwner(C, 0);
1295 hypre_ParCSRMatrixSum(hypre_ParCSRMatrix *A,
1297 hypre_ParCSRMatrix *B)
1299 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
1300 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
1301 hypre_CSRMatrix *B_diag = hypre_ParCSRMatrixDiag(B);
1302 hypre_CSRMatrix *B_offd = hypre_ParCSRMatrixOffd(B);
1305 error = hypre_CSRMatrixSum(A_diag, beta, B_diag);
1306 error = error ? error : hypre_CSRMatrixSum(A_offd, beta, B_offd);
1312 hypre_CSRMatrixSetConstantValues(hypre_CSRMatrix *A,
1313 HYPRE_Complex value)
1315 HYPRE_Complex *A_data = hypre_CSRMatrixData(A);
1316 HYPRE_Int A_nnz = hypre_CSRMatrixNumNonzeros(A);
1319 for (ia = 0; ia < A_nnz; ia++)
1328 hypre_ParCSRMatrixSetConstantValues(hypre_ParCSRMatrix *A,
1329 HYPRE_Complex value)
1331 hypre_CSRMatrixSetConstantValues(hypre_ParCSRMatrixDiag(A), value);
1332 hypre_CSRMatrixSetConstantValues(hypre_ParCSRMatrixOffd(A), value);
1341 #endif // MFEM_USE_MPI