12 #include "../config/config.hpp"
13 #include "../general/error.hpp"
23 #if MFEM_HYPRE_VERSION < 21400
25 #define mfem_hypre_TAlloc(type, size) hypre_TAlloc(type, size)
26 #define mfem_hypre_CTAlloc(type, size) hypre_CTAlloc(type, size)
27 #define mfem_hypre_TFree(ptr) hypre_TFree(ptr)
29 #else // MFEM_HYPRE_VERSION >= 21400
32 #define mfem_hypre_TAlloc(type, size) \
33 hypre_TAlloc(type, size, HYPRE_MEMORY_HOST)
34 #define mfem_hypre_CTAlloc(type, size) \
35 hypre_CTAlloc(type, size, HYPRE_MEMORY_HOST)
36 #define mfem_hypre_TFree(ptr) hypre_TFree(ptr, HYPRE_MEMORY_HOST)
38 #endif // #if MFEM_HYPRE_VERSION < 21400
56 void hypre_CSRMatrixEliminateAXB(hypre_CSRMatrix *A,
57 HYPRE_Int nrows_to_eliminate,
58 HYPRE_Int *rows_to_eliminate,
63 HYPRE_Int irow, jcol, ibeg, iend, pos;
66 HYPRE_Int *Ai = hypre_CSRMatrixI(A);
67 HYPRE_Int *Aj = hypre_CSRMatrixJ(A);
68 HYPRE_Real *Adata = hypre_CSRMatrixData(A);
69 HYPRE_Int nrows = hypre_CSRMatrixNumRows(A);
71 HYPRE_Real *Xdata = hypre_VectorData(X);
72 HYPRE_Real *Bdata = hypre_VectorData(B);
75 for (i = 0; i < nrows; i++)
79 for (j = ibeg; j < iend; j++)
82 pos = hypre_BinarySearch(rows_to_eliminate, jcol, nrows_to_eliminate);
87 Bdata[i] -= a * Xdata[jcol];
93 for (i = 0; i < nrows_to_eliminate; i++)
95 irow = rows_to_eliminate[i];
98 for (j = ibeg; j < iend; j++)
117 void hypre_CSRMatrixEliminateOffdColsAXB(hypre_CSRMatrix *A,
118 HYPRE_Int ncols_to_eliminate,
119 HYPRE_Int *eliminate_cols,
120 HYPRE_Real *eliminate_coefs,
124 HYPRE_Int ibeg, iend, pos;
127 HYPRE_Int *Ai = hypre_CSRMatrixI(A);
128 HYPRE_Int *Aj = hypre_CSRMatrixJ(A);
129 HYPRE_Real *Adata = hypre_CSRMatrixData(A);
130 HYPRE_Int nrows = hypre_CSRMatrixNumRows(A);
132 HYPRE_Real *Bdata = hypre_VectorData(B);
134 for (i = 0; i < nrows; i++)
138 for (j = ibeg; j < iend; j++)
140 pos = hypre_BinarySearch(eliminate_cols, Aj[j], ncols_to_eliminate);
145 Bdata[i] -= a * eliminate_coefs[pos];
156 void hypre_CSRMatrixEliminateOffdRowsAXB(hypre_CSRMatrix *A,
157 HYPRE_Int nrows_to_eliminate,
158 HYPRE_Int *rows_to_eliminate)
160 HYPRE_Int *Ai = hypre_CSRMatrixI(A);
161 HYPRE_Real *Adata = hypre_CSRMatrixData(A);
164 HYPRE_Int irow, ibeg, iend;
166 for (i = 0; i < nrows_to_eliminate; i++)
168 irow = rows_to_eliminate[i];
171 for (j = ibeg; j < iend; j++)
202 void hypre_ParCSRMatrixEliminateAXB(hypre_ParCSRMatrix *A,
203 HYPRE_Int num_rowscols_to_elim,
204 HYPRE_Int *rowscols_to_elim,
208 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
209 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
210 HYPRE_Int diag_nrows = hypre_CSRMatrixNumRows(diag);
211 HYPRE_Int offd_ncols = hypre_CSRMatrixNumCols(offd);
213 hypre_Vector *Xlocal = hypre_ParVectorLocalVector(X);
214 hypre_Vector *Blocal = hypre_ParVectorLocalVector(B);
216 HYPRE_Real *Bdata = hypre_VectorData(Blocal);
217 HYPRE_Real *Xdata = hypre_VectorData(Xlocal);
219 HYPRE_Int num_offd_cols_to_elim;
220 HYPRE_Int *offd_cols_to_elim;
221 HYPRE_Real *eliminate_coefs;
224 hypre_ParCSRCommHandle *comm_handle;
225 hypre_ParCSRCommPkg *comm_pkg;
227 HYPRE_Int
index, start;
228 HYPRE_Int i, j, k, irow;
230 HYPRE_Real *eliminate_row = mfem_hypre_CTAlloc(HYPRE_Real, diag_nrows);
231 HYPRE_Real *eliminate_col = mfem_hypre_CTAlloc(HYPRE_Real, offd_ncols);
232 HYPRE_Real *buf_data, coef;
235 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
238 hypre_MatvecCommPkgCreate(A);
239 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
245 for (i = 0; i < diag_nrows; i++)
247 eliminate_row[i] = std::numeric_limits<HYPRE_Real>::quiet_NaN();
249 for (i = 0; i < num_rowscols_to_elim; i++)
251 irow = rowscols_to_elim[i];
252 eliminate_row[irow] = Xdata[irow];
257 num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
258 buf_data = mfem_hypre_CTAlloc(HYPRE_Real,
259 hypre_ParCSRCommPkgSendMapStart(comm_pkg,
262 for (i = 0; i < num_sends; i++)
264 start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
265 for (j = start; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++)
267 k = hypre_ParCSRCommPkgSendMapElmt(comm_pkg,j);
268 buf_data[index++] = eliminate_row[k];
271 comm_handle = hypre_ParCSRCommHandleCreate(1, comm_pkg,
272 buf_data, eliminate_col);
275 hypre_CSRMatrixEliminateAXB(diag, num_rowscols_to_elim, rowscols_to_elim,
279 hypre_ParCSRCommHandleDestroy(comm_handle);
282 num_offd_cols_to_elim = 0;
283 for (i = 0; i < offd_ncols; i++)
285 coef = eliminate_col[i];
288 num_offd_cols_to_elim++;
292 offd_cols_to_elim = mfem_hypre_CTAlloc(HYPRE_Int, num_offd_cols_to_elim);
293 eliminate_coefs = mfem_hypre_CTAlloc(HYPRE_Real, num_offd_cols_to_elim);
296 num_offd_cols_to_elim = 0;
297 for (i = 0; i < offd_ncols; i++)
299 coef = eliminate_col[i];
302 offd_cols_to_elim[num_offd_cols_to_elim] = i;
303 eliminate_coefs[num_offd_cols_to_elim] = coef;
304 num_offd_cols_to_elim++;
308 mfem_hypre_TFree(buf_data);
309 mfem_hypre_TFree(eliminate_col);
310 mfem_hypre_TFree(eliminate_row);
313 hypre_CSRMatrixEliminateOffdColsAXB(offd, num_offd_cols_to_elim,
315 eliminate_coefs, Blocal);
317 hypre_CSRMatrixEliminateOffdRowsAXB(offd, num_rowscols_to_elim,
321 for (
int i = 0; i < num_rowscols_to_elim; i++)
323 irow = rowscols_to_elim[i];
324 Bdata[irow] = Xdata[irow];
327 mfem_hypre_TFree(offd_cols_to_elim);
328 mfem_hypre_TFree(eliminate_coefs);
341 void hypre_CSRMatrixElimCreate(hypre_CSRMatrix *A,
343 HYPRE_Int nrows, HYPRE_Int *rows,
344 HYPRE_Int ncols, HYPRE_Int *cols,
348 HYPRE_Int A_beg, A_end;
350 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
351 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
352 HYPRE_Int A_rows = hypre_CSRMatrixNumRows(A);
354 hypre_CSRMatrixI(Ae) = mfem_hypre_TAlloc(HYPRE_Int, A_rows+1);
356 HYPRE_Int *Ae_i = hypre_CSRMatrixI(Ae);
359 for (i = 0; i < A_rows; i++)
366 if (hypre_BinarySearch(rows, i, nrows) >= 0)
369 nnz += A_end - A_beg;
373 for (j = A_beg; j < A_end; j++)
375 col_mark[A_j[j]] = 1;
382 for (j = A_beg; j < A_end; j++)
385 if (hypre_BinarySearch(cols, col, ncols) >= 0)
388 if (col_mark) { col_mark[col] = 1; }
395 hypre_CSRMatrixJ(Ae) = mfem_hypre_TAlloc(HYPRE_Int, nnz);
396 hypre_CSRMatrixData(Ae) = mfem_hypre_TAlloc(HYPRE_Real, nnz);
397 hypre_CSRMatrixNumNonzeros(Ae) = nnz;
407 void hypre_CSRMatrixEliminateRowsCols(hypre_CSRMatrix *A,
409 HYPRE_Int nrows, HYPRE_Int *rows,
410 HYPRE_Int ncols, HYPRE_Int *cols,
411 int diag, HYPRE_Int* col_remap)
413 HYPRE_Int i, j, k, col;
414 HYPRE_Int A_beg, Ae_beg, A_end;
417 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
418 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
419 HYPRE_Real *A_data = hypre_CSRMatrixData(A);
420 HYPRE_Int A_rows = hypre_CSRMatrixNumRows(A);
422 HYPRE_Int *Ae_i = hypre_CSRMatrixI(Ae);
423 HYPRE_Int *Ae_j = hypre_CSRMatrixJ(Ae);
424 HYPRE_Real *Ae_data = hypre_CSRMatrixData(Ae);
426 for (i = 0; i < A_rows; i++)
432 if (hypre_BinarySearch(rows, i, nrows) >= 0)
435 for (j = A_beg, k = Ae_beg; j < A_end; j++, k++)
438 Ae_j[k] = col_remap ? col_remap[col] : col;
439 a = (diag && col == i) ? 1.0 : 0.0;
440 Ae_data[k] = A_data[j] -
a;
447 for (j = A_beg, k = Ae_beg; j < A_end; j++)
450 if (hypre_BinarySearch(cols, col, ncols) >= 0)
452 Ae_j[k] = col_remap ? col_remap[col] : col;
453 Ae_data[k] = A_data[j];
465 void hypre_CSRMatrixEliminateRows(hypre_CSRMatrix *A,
466 HYPRE_Int nrows,
const HYPRE_Int *rows)
468 HYPRE_Int irow, i, j;
469 HYPRE_Int A_beg, A_end;
471 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
472 HYPRE_Real *A_data = hypre_CSRMatrixData(A);
474 for (i = 0; i < nrows; i++)
480 for (j = A_beg; j < A_end; j++)
503 void hypre_ParCSRMatrixEliminateAAe(hypre_ParCSRMatrix *A,
504 hypre_ParCSRMatrix **Ae,
505 HYPRE_Int num_rowscols_to_elim,
506 HYPRE_Int *rowscols_to_elim,
511 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
512 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
513 HYPRE_Int A_diag_ncols = hypre_CSRMatrixNumCols(A_diag);
514 HYPRE_Int A_offd_ncols = hypre_CSRMatrixNumCols(A_offd);
516 *Ae = hypre_ParCSRMatrixCreate(hypre_ParCSRMatrixComm(A),
517 hypre_ParCSRMatrixGlobalNumRows(A),
518 hypre_ParCSRMatrixGlobalNumCols(A),
519 hypre_ParCSRMatrixRowStarts(A),
520 hypre_ParCSRMatrixColStarts(A),
523 hypre_ParCSRMatrixSetRowStartsOwner(*Ae, 0);
524 hypre_ParCSRMatrixSetColStartsOwner(*Ae, 0);
526 hypre_CSRMatrix *Ae_diag = hypre_ParCSRMatrixDiag(*Ae);
527 hypre_CSRMatrix *Ae_offd = hypre_ParCSRMatrixOffd(*Ae);
528 HYPRE_Int Ae_offd_ncols;
530 HYPRE_Int num_offd_cols_to_elim;
531 HYPRE_Int *offd_cols_to_elim;
533 HYPRE_Int *A_col_map_offd = hypre_ParCSRMatrixColMapOffd(A);
534 HYPRE_Int *Ae_col_map_offd;
537 HYPRE_Int *col_remap;
541 hypre_ParCSRCommHandle *comm_handle;
542 hypre_ParCSRCommPkg *comm_pkg;
543 HYPRE_Int num_sends, *int_buf_data;
544 HYPRE_Int
index, start;
546 HYPRE_Int *eliminate_diag_col = mfem_hypre_CTAlloc(HYPRE_Int, A_diag_ncols);
547 HYPRE_Int *eliminate_offd_col = mfem_hypre_CTAlloc(HYPRE_Int, A_offd_ncols);
550 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
553 hypre_MatvecCommPkgCreate(A);
554 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
558 for (i = 0; i < A_diag_ncols; i++)
560 eliminate_diag_col[i] = 0;
562 for (i = 0; i < num_rowscols_to_elim; i++)
564 eliminate_diag_col[rowscols_to_elim[i]] = 1;
569 num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
570 int_buf_data = mfem_hypre_CTAlloc(
572 hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends));
574 for (i = 0; i < num_sends; i++)
576 start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
577 for (j = start; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++)
579 k = hypre_ParCSRCommPkgSendMapElmt(comm_pkg, j);
580 int_buf_data[index++] = eliminate_diag_col[k];
583 comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg,
584 int_buf_data, eliminate_offd_col);
589 hypre_CSRMatrixElimCreate(A_diag, Ae_diag,
591 num_rowscols_to_elim, rowscols_to_elim,
594 hypre_CSRMatrixEliminateRowsCols(A_diag, Ae_diag,
596 num_rowscols_to_elim, rowscols_to_elim,
601 hypre_CSRMatrixElimCreate(A_diag, Ae_diag,
602 num_rowscols_to_elim, rowscols_to_elim,
603 num_rowscols_to_elim, rowscols_to_elim,
606 hypre_CSRMatrixEliminateRowsCols(A_diag, Ae_diag,
607 num_rowscols_to_elim, rowscols_to_elim,
608 num_rowscols_to_elim, rowscols_to_elim,
612 hypre_CSRMatrixReorder(Ae_diag);
615 hypre_ParCSRCommHandleDestroy(comm_handle);
618 num_offd_cols_to_elim = 0;
619 for (i = 0; i < A_offd_ncols; i++)
621 if (eliminate_offd_col[i]) { num_offd_cols_to_elim++; }
624 offd_cols_to_elim = mfem_hypre_CTAlloc(HYPRE_Int, num_offd_cols_to_elim);
627 num_offd_cols_to_elim = 0;
628 for (i = 0; i < A_offd_ncols; i++)
630 if (eliminate_offd_col[i])
632 offd_cols_to_elim[num_offd_cols_to_elim++] = i;
636 mfem_hypre_TFree(int_buf_data);
637 mfem_hypre_TFree(eliminate_offd_col);
638 mfem_hypre_TFree(eliminate_diag_col);
642 col_mark = mfem_hypre_CTAlloc(HYPRE_Int, A_offd_ncols);
643 col_remap = mfem_hypre_CTAlloc(HYPRE_Int, A_offd_ncols);
647 hypre_CSRMatrixElimCreate(A_offd, Ae_offd,
649 num_offd_cols_to_elim, offd_cols_to_elim,
652 for (i = k = 0; i < A_offd_ncols; i++)
654 if (col_mark[i]) { col_remap[i] = k++; }
657 hypre_CSRMatrixEliminateRowsCols(A_offd, Ae_offd,
659 num_offd_cols_to_elim, offd_cols_to_elim,
664 hypre_CSRMatrixElimCreate(A_offd, Ae_offd,
665 num_rowscols_to_elim, rowscols_to_elim,
666 num_offd_cols_to_elim, offd_cols_to_elim,
669 for (i = k = 0; i < A_offd_ncols; i++)
671 if (col_mark[i]) { col_remap[i] = k++; }
674 hypre_CSRMatrixEliminateRowsCols(A_offd, Ae_offd,
675 num_rowscols_to_elim, rowscols_to_elim,
676 num_offd_cols_to_elim, offd_cols_to_elim,
682 for (i = 0; i < A_offd_ncols; i++)
684 if (col_mark[i]) { Ae_offd_ncols++; }
687 Ae_col_map_offd = mfem_hypre_CTAlloc(HYPRE_Int, Ae_offd_ncols);
690 for (i = 0; i < A_offd_ncols; i++)
694 Ae_col_map_offd[Ae_offd_ncols++] = A_col_map_offd[i];
698 hypre_ParCSRMatrixColMapOffd(*Ae) = Ae_col_map_offd;
699 hypre_CSRMatrixNumCols(Ae_offd) = Ae_offd_ncols;
701 mfem_hypre_TFree(col_remap);
702 mfem_hypre_TFree(col_mark);
703 mfem_hypre_TFree(offd_cols_to_elim);
705 hypre_ParCSRMatrixSetNumNonzeros(*Ae);
706 hypre_MatvecCommPkgCreate(*Ae);
711 void hypre_ParCSRMatrixEliminateRows(hypre_ParCSRMatrix *A,
712 HYPRE_Int num_rows_to_elim,
713 const HYPRE_Int *rows_to_elim)
715 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
716 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
717 hypre_CSRMatrixEliminateRows(A_diag, num_rows_to_elim, rows_to_elim);
718 hypre_CSRMatrixEliminateRows(A_offd, num_rows_to_elim, rows_to_elim);
726 void hypre_CSRMatrixSplit(hypre_CSRMatrix *A,
727 HYPRE_Int nr, HYPRE_Int nc,
728 HYPRE_Int *row_block_num, HYPRE_Int *col_block_num,
729 hypre_CSRMatrix **blocks)
731 HYPRE_Int i, j, k, bi, bj;
733 HYPRE_Int* A_i = hypre_CSRMatrixI(A);
734 HYPRE_Int* A_j = hypre_CSRMatrixJ(A);
735 HYPRE_Complex* A_data = hypre_CSRMatrixData(A);
737 HYPRE_Int A_rows = hypre_CSRMatrixNumRows(A);
738 HYPRE_Int A_cols = hypre_CSRMatrixNumCols(A);
740 HYPRE_Int *num_rows = mfem_hypre_CTAlloc(HYPRE_Int, nr);
741 HYPRE_Int *num_cols = mfem_hypre_CTAlloc(HYPRE_Int, nc);
743 HYPRE_Int *block_row = mfem_hypre_TAlloc(HYPRE_Int, A_rows);
744 HYPRE_Int *block_col = mfem_hypre_TAlloc(HYPRE_Int, A_cols);
746 for (i = 0; i < A_rows; i++)
748 block_row[i] = num_rows[row_block_num[i]]++;
750 for (j = 0; j < A_cols; j++)
752 block_col[j] = num_cols[col_block_num[j]]++;
756 for (i = 0; i < nr; i++)
758 for (j = 0; j < nc; j++)
760 hypre_CSRMatrix *B = hypre_CSRMatrixCreate(num_rows[i], num_cols[j], 0);
761 hypre_CSRMatrixI(B) = mfem_hypre_CTAlloc(HYPRE_Int, num_rows[i] + 1);
762 blocks[i*nc + j] = B;
767 for (i = 0; i < A_rows; i++)
769 bi = row_block_num[i];
770 for (j = A_i[i]; j < A_i[i+1]; j++)
772 bj = col_block_num[A_j[j]];
773 hypre_CSRMatrix *B = blocks[bi*nc + bj];
774 hypre_CSRMatrixI(B)[block_row[i] + 1]++;
779 for (k = 0; k < nr*nc; k++)
781 hypre_CSRMatrix *B = blocks[k];
782 HYPRE_Int* B_i = hypre_CSRMatrixI(B);
784 HYPRE_Int nnz = 0, rs;
785 for (
int k = 1; k <= hypre_CSRMatrixNumRows(B); k++)
787 rs = B_i[k], B_i[k] = nnz, nnz += rs;
790 hypre_CSRMatrixJ(B) = mfem_hypre_TAlloc(HYPRE_Int, nnz);
791 hypre_CSRMatrixData(B) = mfem_hypre_TAlloc(HYPRE_Complex, nnz);
792 hypre_CSRMatrixNumNonzeros(B) = nnz;
796 for (i = 0; i < A_rows; i++)
798 bi = row_block_num[i];
799 for (j = A_i[i]; j < A_i[i+1]; j++)
802 bj = col_block_num[k];
803 hypre_CSRMatrix *B = blocks[bi*nc + bj];
804 HYPRE_Int *bii = hypre_CSRMatrixI(B) + block_row[i] + 1;
805 hypre_CSRMatrixJ(B)[*bii] = block_col[k];
806 hypre_CSRMatrixData(B)[*bii] = A_data[j];
811 mfem_hypre_TFree(block_col);
812 mfem_hypre_TFree(block_row);
814 mfem_hypre_TFree(num_cols);
815 mfem_hypre_TFree(num_rows);
819 void hypre_ParCSRMatrixSplit(hypre_ParCSRMatrix *A,
820 HYPRE_Int nr, HYPRE_Int nc,
821 hypre_ParCSRMatrix **blocks,
822 int interleaved_rows,
int interleaved_cols)
826 MPI_Comm comm = hypre_ParCSRMatrixComm(A);
828 hypre_CSRMatrix *Adiag = hypre_ParCSRMatrixDiag(A);
829 hypre_CSRMatrix *Aoffd = hypre_ParCSRMatrixOffd(A);
831 HYPRE_Int global_rows = hypre_ParCSRMatrixGlobalNumRows(A);
832 HYPRE_Int global_cols = hypre_ParCSRMatrixGlobalNumCols(A);
834 HYPRE_Int local_rows = hypre_CSRMatrixNumRows(Adiag);
835 HYPRE_Int local_cols = hypre_CSRMatrixNumCols(Adiag);
836 HYPRE_Int offd_cols = hypre_CSRMatrixNumCols(Aoffd);
838 hypre_assert(local_rows % nr == 0 && local_cols % nc == 0);
839 hypre_assert(global_rows % nr == 0 && global_cols % nc == 0);
841 HYPRE_Int block_rows = local_rows / nr;
842 HYPRE_Int block_cols = local_cols / nc;
843 HYPRE_Int num_blocks = nr * nc;
846 HYPRE_Int *row_block_num = mfem_hypre_TAlloc(HYPRE_Int, local_rows);
847 HYPRE_Int *col_block_num = mfem_hypre_TAlloc(HYPRE_Int, local_cols);
849 for (i = 0; i < local_rows; i++)
851 row_block_num[i] = interleaved_rows ? (i % nr) : (i / block_rows);
853 for (i = 0; i < local_cols; i++)
855 col_block_num[i] = interleaved_cols ? (i % nc) : (i / block_cols);
859 HYPRE_Int* offd_col_block_num = mfem_hypre_TAlloc(HYPRE_Int, offd_cols);
860 hypre_ParCSRCommHandle *comm_handle;
861 HYPRE_Int *int_buf_data;
864 hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg(A);
867 hypre_MatvecCommPkgCreate(A);
868 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
872 HYPRE_Int *count = mfem_hypre_CTAlloc(HYPRE_Int, nc);
873 HYPRE_Int *block_global_col = mfem_hypre_TAlloc(HYPRE_Int, local_cols);
874 HYPRE_Int first_col = hypre_ParCSRMatrixFirstColDiag(A) / nc;
875 for (i = 0; i < local_cols; i++)
877 block_global_col[i] = first_col + count[col_block_num[i]]++;
879 mfem_hypre_TFree(count);
882 HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
883 int_buf_data = mfem_hypre_CTAlloc(
885 hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends));
886 HYPRE_Int start, index = 0;
887 for (i = 0; i < num_sends; i++)
889 start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
890 for (j = start; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++)
892 k = hypre_ParCSRCommPkgSendMapElmt(comm_pkg, j);
893 int_buf_data[index++] = col_block_num[k] + nc*block_global_col[k];
896 mfem_hypre_TFree(block_global_col);
898 comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data,
903 HYPRE_Int num_procs = 1;
904 if (!hypre_ParCSRMatrixAssumedPartition(A))
906 hypre_MPI_Comm_size(comm, &num_procs);
909 HYPRE_Int *row_starts = mfem_hypre_TAlloc(HYPRE_Int, num_procs+1);
910 HYPRE_Int *col_starts = mfem_hypre_TAlloc(HYPRE_Int, num_procs+1);
911 for (i = 0; i <= num_procs; i++)
913 row_starts[i] = hypre_ParCSRMatrixRowStarts(A)[i] / nr;
914 col_starts[i] = hypre_ParCSRMatrixColStarts(A)[i] / nc;
917 for (i = 0; i < num_blocks; i++)
919 blocks[i] = hypre_ParCSRMatrixCreate(comm,
920 global_rows/nr, global_cols/nc,
921 row_starts, col_starts, 0, 0, 0);
925 hypre_CSRMatrix **csr_blocks = mfem_hypre_TAlloc(hypre_CSRMatrix*, nr*nc);
926 hypre_CSRMatrixSplit(Adiag, nr, nc, row_block_num, col_block_num,
929 for (i = 0; i < num_blocks; i++)
931 mfem_hypre_TFree(hypre_ParCSRMatrixDiag(blocks[i]));
932 hypre_ParCSRMatrixDiag(blocks[i]) = csr_blocks[i];
936 hypre_ParCSRCommHandleDestroy(comm_handle);
937 mfem_hypre_TFree(int_buf_data);
940 HYPRE_Int* offd_global_col = mfem_hypre_TAlloc(HYPRE_Int, offd_cols);
941 for (i = 0; i < offd_cols; i++)
943 offd_global_col[i] = offd_col_block_num[i] / nc;
944 offd_col_block_num[i] %= nc;
948 hypre_CSRMatrixSplit(Aoffd, nr, nc, row_block_num, offd_col_block_num,
951 for (i = 0; i < num_blocks; i++)
953 mfem_hypre_TFree(hypre_ParCSRMatrixOffd(blocks[i]));
954 hypre_ParCSRMatrixOffd(blocks[i]) = csr_blocks[i];
957 mfem_hypre_TFree(csr_blocks);
958 mfem_hypre_TFree(col_block_num);
959 mfem_hypre_TFree(row_block_num);
962 for (
int bi = 0; bi < nr; bi++)
964 for (
int bj = 0; bj < nc; bj++)
966 hypre_ParCSRMatrix *block = blocks[bi*nc + bj];
967 hypre_CSRMatrix *block_offd = hypre_ParCSRMatrixOffd(block);
968 HYPRE_Int block_offd_cols = hypre_CSRMatrixNumCols(block_offd);
970 HYPRE_Int *block_col_map = mfem_hypre_TAlloc(HYPRE_Int,
972 for (i = j = 0; i < offd_cols; i++)
974 HYPRE_Int bn = offd_col_block_num[i];
975 if (bn == bj) { block_col_map[j++] = offd_global_col[i]; }
977 hypre_assert(j == block_offd_cols);
979 hypre_ParCSRMatrixColMapOffd(block) = block_col_map;
983 mfem_hypre_TFree(offd_global_col);
984 mfem_hypre_TFree(offd_col_block_num);
987 for (i = 0; i < num_blocks; i++)
989 hypre_ParCSRMatrixSetNumNonzeros(blocks[i]);
990 hypre_MatvecCommPkgCreate(blocks[i]);
992 hypre_ParCSRMatrixOwnsData(blocks[i]) = 1;
995 hypre_ParCSRMatrixOwnsRowStarts(blocks[i]) = !i;
996 hypre_ParCSRMatrixOwnsColStarts(blocks[i]) = !i;
1001 void hypre_CSRMatrixBooleanMatvec(hypre_CSRMatrix *A,
1008 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
1009 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
1010 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A);
1012 HYPRE_Int *A_rownnz = hypre_CSRMatrixRownnz(A);
1013 HYPRE_Int num_rownnz = hypre_CSRMatrixNumRownnz(A);
1015 HYPRE_Bool *x_data = x;
1016 HYPRE_Bool *y_data = y;
1018 HYPRE_Bool temp, tempx;
1024 HYPRE_Real xpar=0.7;
1032 #ifdef HYPRE_USING_OPENMP
1033 #pragma omp parallel for private(i) HYPRE_SMP_SCHEDULE
1035 for (i = 0; i < num_rows; i++)
1037 y_data[i] = y_data[i] && beta;
1048 #ifdef HYPRE_USING_OPENMP
1049 #pragma omp parallel for private(i) HYPRE_SMP_SCHEDULE
1051 for (i = 0; i < num_rows; i++)
1067 if (num_rownnz < xpar*(num_rows))
1069 #ifdef HYPRE_USING_OPENMP
1070 #pragma omp parallel for private(i,jj,m,tempx) HYPRE_SMP_SCHEDULE
1072 for (i = 0; i < num_rownnz; i++)
1077 for (jj = A_i[m]; jj < A_i[m+1]; jj++)
1080 tempx = tempx || x_data[A_j[jj]];
1082 y_data[m] = y_data[m] || tempx;
1087 #ifdef HYPRE_USING_OPENMP
1088 #pragma omp parallel for private(i,jj,temp) HYPRE_SMP_SCHEDULE
1090 for (i = 0; i < num_rows; i++)
1093 for (jj = A_i[i]; jj < A_i[i+1]; jj++)
1096 temp = temp || x_data[A_j[jj]];
1098 y_data[i] = y_data[i] || temp;
1109 void hypre_CSRMatrixBooleanMatvecT(hypre_CSRMatrix *A,
1116 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
1117 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
1118 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A);
1119 HYPRE_Int num_cols = hypre_CSRMatrixNumCols(A);
1121 HYPRE_Bool *x_data = x;
1122 HYPRE_Bool *y_data = y;
1132 for (i = 0; i < num_cols; i++)
1156 for (i = 0; i < num_rows; i++)
1160 for (jj = A_i[i]; jj < A_i[i+1]; jj++)
1172 hypre_ParCSRCommHandle *
1173 hypre_ParCSRCommHandleCreate_bool(HYPRE_Int job,
1174 hypre_ParCSRCommPkg *comm_pkg,
1175 HYPRE_Bool *send_data,
1176 HYPRE_Bool *recv_data)
1178 HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
1179 HYPRE_Int num_recvs = hypre_ParCSRCommPkgNumRecvs(comm_pkg);
1180 MPI_Comm comm = hypre_ParCSRCommPkgComm(comm_pkg);
1182 hypre_ParCSRCommHandle *comm_handle;
1183 HYPRE_Int num_requests;
1184 hypre_MPI_Request *requests;
1187 HYPRE_Int my_id, num_procs;
1188 HYPRE_Int ip, vec_start, vec_len;
1190 num_requests = num_sends + num_recvs;
1191 requests = mfem_hypre_CTAlloc(hypre_MPI_Request, num_requests);
1193 hypre_MPI_Comm_size(comm, &num_procs);
1194 hypre_MPI_Comm_rank(comm, &my_id);
1201 HYPRE_Bool *d_send_data = (HYPRE_Bool *) send_data;
1202 HYPRE_Bool *d_recv_data = (HYPRE_Bool *) recv_data;
1203 for (i = 0; i < num_recvs; i++)
1205 ip = hypre_ParCSRCommPkgRecvProc(comm_pkg, i);
1206 vec_start = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i);
1207 vec_len = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i+1)-vec_start;
1208 hypre_MPI_Irecv(&d_recv_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1209 ip, 0, comm, &requests[j++]);
1211 for (i = 0; i < num_sends; i++)
1213 vec_start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
1214 vec_len = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1)-vec_start;
1215 ip = hypre_ParCSRCommPkgSendProc(comm_pkg, i);
1216 hypre_MPI_Isend(&d_send_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1217 ip, 0, comm, &requests[j++]);
1223 HYPRE_Bool *d_send_data = (HYPRE_Bool *) send_data;
1224 HYPRE_Bool *d_recv_data = (HYPRE_Bool *) recv_data;
1225 for (i = 0; i < num_sends; i++)
1227 vec_start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
1228 vec_len = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1)-vec_start;
1229 ip = hypre_ParCSRCommPkgSendProc(comm_pkg, i);
1230 hypre_MPI_Irecv(&d_recv_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1231 ip, 0, comm, &requests[j++]);
1233 for (i = 0; i < num_recvs; i++)
1235 ip = hypre_ParCSRCommPkgRecvProc(comm_pkg, i);
1236 vec_start = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i);
1237 vec_len = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i+1)-vec_start;
1238 hypre_MPI_Isend(&d_send_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1239 ip, 0, comm, &requests[j++]);
1248 comm_handle = mfem_hypre_CTAlloc(hypre_ParCSRCommHandle, 1);
1250 hypre_ParCSRCommHandleCommPkg(comm_handle) = comm_pkg;
1251 hypre_ParCSRCommHandleSendData(comm_handle) = send_data;
1252 hypre_ParCSRCommHandleRecvData(comm_handle) = recv_data;
1253 hypre_ParCSRCommHandleNumRequests(comm_handle) = num_requests;
1254 hypre_ParCSRCommHandleRequests(comm_handle) = requests;
1260 void hypre_ParCSRMatrixBooleanMatvec(hypre_ParCSRMatrix *A,
1266 hypre_ParCSRCommHandle *comm_handle;
1267 hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg(A);
1268 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
1269 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
1271 HYPRE_Int num_cols_offd = hypre_CSRMatrixNumCols(offd);
1272 HYPRE_Int num_sends, i, j,
index;
1274 HYPRE_Bool *x_tmp, *x_buf;
1276 x_tmp = mfem_hypre_CTAlloc(HYPRE_Bool, num_cols_offd);
1284 hypre_MatvecCommPkgCreate(A);
1285 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
1288 num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
1289 x_buf = mfem_hypre_CTAlloc(
1290 HYPRE_Bool, hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends));
1293 for (i = 0; i < num_sends; i++)
1295 j = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
1296 for ( ; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++)
1298 x_buf[index++] = x[hypre_ParCSRCommPkgSendMapElmt(comm_pkg, j)];
1302 comm_handle = hypre_ParCSRCommHandleCreate_bool(1, comm_pkg, x_buf, x_tmp);
1304 hypre_CSRMatrixBooleanMatvec(diag, alpha, x, beta, y);
1306 hypre_ParCSRCommHandleDestroy(comm_handle);
1310 hypre_CSRMatrixBooleanMatvec(offd, alpha, x_tmp, 1, y);
1313 mfem_hypre_TFree(x_buf);
1314 mfem_hypre_TFree(x_tmp);
1318 void hypre_ParCSRMatrixBooleanMatvecT(hypre_ParCSRMatrix *A,
1324 hypre_ParCSRCommHandle *comm_handle;
1325 hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg(A);
1326 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
1327 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
1331 HYPRE_Int num_cols_offd = hypre_CSRMatrixNumCols(offd);
1333 HYPRE_Int i, j, jj, end, num_sends;
1335 y_tmp = mfem_hypre_TAlloc(HYPRE_Bool, num_cols_offd);
1343 hypre_MatvecCommPkgCreate(A);
1344 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
1347 num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
1348 y_buf = mfem_hypre_CTAlloc(
1349 HYPRE_Bool, hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends));
1353 #if MFEM_HYPRE_VERSION >= 21100
1357 hypre_CSRMatrixBooleanMatvec(A->offdT, alpha, x, 0, y_tmp);
1362 hypre_CSRMatrixBooleanMatvecT(offd, alpha, x, 0, y_tmp);
1366 comm_handle = hypre_ParCSRCommHandleCreate_bool(2, comm_pkg, y_tmp, y_buf);
1368 #if MFEM_HYPRE_VERSION >= 21100
1372 hypre_CSRMatrixBooleanMatvec(A->diagT, alpha, x, beta, y);
1377 hypre_CSRMatrixBooleanMatvecT(diag, alpha, x, beta, y);
1380 hypre_ParCSRCommHandleDestroy(comm_handle);
1382 for (i = 0; i < num_sends; i++)
1384 end = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1);
1385 for (j = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i); j < end; j++)
1387 jj = hypre_ParCSRCommPkgSendMapElmt(comm_pkg, j);
1388 y[jj] = y[jj] || y_buf[j];
1392 mfem_hypre_TFree(y_buf);
1393 mfem_hypre_TFree(y_tmp);
1397 hypre_CSRMatrixSum(hypre_CSRMatrix *A,
1401 HYPRE_Complex *A_data = hypre_CSRMatrixData(A);
1402 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
1403 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
1404 HYPRE_Int nrows_A = hypre_CSRMatrixNumRows(A);
1405 HYPRE_Int ncols_A = hypre_CSRMatrixNumCols(A);
1406 HYPRE_Complex *B_data = hypre_CSRMatrixData(B);
1407 HYPRE_Int *B_i = hypre_CSRMatrixI(B);
1408 HYPRE_Int *B_j = hypre_CSRMatrixJ(B);
1409 HYPRE_Int nrows_B = hypre_CSRMatrixNumRows(B);
1410 HYPRE_Int ncols_B = hypre_CSRMatrixNumCols(B);
1412 HYPRE_Int ia, j, pos;
1415 if (nrows_A != nrows_B || ncols_A != ncols_B)
1420 marker = mfem_hypre_CTAlloc(HYPRE_Int, ncols_A);
1421 for (ia = 0; ia < ncols_A; ia++)
1426 for (ia = 0; ia < nrows_A; ia++)
1428 for (j = A_i[ia]; j < A_i[ia+1]; j++)
1433 for (j = B_i[ia]; j < B_i[ia+1]; j++)
1435 pos = marker[B_j[j]];
1440 A_data[pos] += beta * B_data[j];
1444 mfem_hypre_TFree(marker);
1448 hypre_ParCSRMatrix *
1449 hypre_ParCSRMatrixAdd(hypre_ParCSRMatrix *A,
1450 hypre_ParCSRMatrix *B)
1452 MPI_Comm comm = hypre_ParCSRMatrixComm(A);
1453 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
1454 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
1455 HYPRE_Int *A_cmap = hypre_ParCSRMatrixColMapOffd(A);
1456 HYPRE_Int A_cmap_size = hypre_CSRMatrixNumCols(A_offd);
1457 hypre_CSRMatrix *B_diag = hypre_ParCSRMatrixDiag(B);
1458 hypre_CSRMatrix *B_offd = hypre_ParCSRMatrixOffd(B);
1459 HYPRE_Int *B_cmap = hypre_ParCSRMatrixColMapOffd(B);
1460 HYPRE_Int B_cmap_size = hypre_CSRMatrixNumCols(B_offd);
1461 hypre_ParCSRMatrix *C;
1462 hypre_CSRMatrix *C_diag;
1463 hypre_CSRMatrix *C_offd;
1466 HYPRE_Int cmap_differ;
1470 if (A_cmap_size != B_cmap_size)
1476 for (im = 0; im < A_cmap_size; im++)
1478 if (A_cmap[im] != B_cmap[im])
1486 if ( cmap_differ == 0 )
1493 C_diag = hypre_CSRMatrixAdd(A_diag, B_diag);
1498 C_offd = hypre_CSRMatrixAdd(A_offd, B_offd);
1501 hypre_CSRMatrixDestroy(C_diag);
1505 C_cmap = mfem_hypre_TAlloc(HYPRE_Int, A_cmap_size);
1506 for (im = 0; im < A_cmap_size; im++)
1508 C_cmap[im] = A_cmap[im];
1511 C = hypre_ParCSRMatrixCreate(comm,
1512 hypre_ParCSRMatrixGlobalNumRows(A),
1513 hypre_ParCSRMatrixGlobalNumCols(A),
1514 hypre_ParCSRMatrixRowStarts(A),
1515 hypre_ParCSRMatrixColStarts(A),
1516 hypre_CSRMatrixNumCols(C_offd),
1517 hypre_CSRMatrixNumNonzeros(C_diag),
1518 hypre_CSRMatrixNumNonzeros(C_offd));
1522 hypre_CSRMatrixDestroy(hypre_ParCSRMatrixDiag(C));
1523 hypre_CSRMatrixDestroy(hypre_ParCSRMatrixOffd(C));
1524 hypre_ParCSRMatrixDiag(C) = C_diag;
1525 hypre_ParCSRMatrixOffd(C) = C_offd;
1527 hypre_ParCSRMatrixColMapOffd(C) = C_cmap;
1535 hypre_CSRMatrix * csr_A;
1536 hypre_CSRMatrix * csr_B;
1537 hypre_CSRMatrix * csr_C_temp;
1540 csr_A = hypre_MergeDiagAndOffd(A);
1543 csr_B = hypre_MergeDiagAndOffd(B);
1546 csr_C_temp = hypre_CSRMatrixAdd(csr_A,csr_B);
1549 ierr += hypre_CSRMatrixDestroy(csr_A);
1550 ierr += hypre_CSRMatrixDestroy(csr_B);
1553 C = hypre_ParCSRMatrixCreate(hypre_ParCSRMatrixComm(A),
1554 hypre_ParCSRMatrixGlobalNumRows(A),
1555 hypre_ParCSRMatrixGlobalNumCols(A),
1556 hypre_ParCSRMatrixRowStarts(A),
1557 hypre_ParCSRMatrixColStarts(A),
1564 ierr += GenerateDiagAndOffd(csr_C_temp, C,
1565 hypre_ParCSRMatrixFirstColDiag(A),
1566 hypre_ParCSRMatrixLastColDiag(A));
1569 ierr += hypre_CSRMatrixDestroy(csr_C_temp);
1571 MFEM_VERIFY(ierr == 0,
"");
1577 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(C));
1580 hypre_ParCSRMatrixSetDataOwner(C, 1);
1582 hypre_ParCSRMatrixSetRowStartsOwner(C, 0);
1583 hypre_ParCSRMatrixSetColStartsOwner(C, 0);
1589 hypre_ParCSRMatrixSum(hypre_ParCSRMatrix *A,
1591 hypre_ParCSRMatrix *B)
1593 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
1594 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
1595 hypre_CSRMatrix *B_diag = hypre_ParCSRMatrixDiag(B);
1596 hypre_CSRMatrix *B_offd = hypre_ParCSRMatrixOffd(B);
1597 HYPRE_Int ncols_B_offd = hypre_CSRMatrixNumCols(B_offd);
1600 error = hypre_CSRMatrixSum(A_diag, beta, B_diag);
1601 if (ncols_B_offd > 0)
1603 error = error ? error : hypre_CSRMatrixSum(A_offd, beta, B_offd);
1610 hypre_CSRMatrixSetConstantValues(hypre_CSRMatrix *A,
1611 HYPRE_Complex value)
1613 HYPRE_Complex *A_data = hypre_CSRMatrixData(A);
1614 HYPRE_Int A_nnz = hypre_CSRMatrixNumNonzeros(A);
1617 for (ia = 0; ia < A_nnz; ia++)
1626 hypre_ParCSRMatrixSetConstantValues(hypre_ParCSRMatrix *A,
1627 HYPRE_Complex value)
1629 hypre_CSRMatrixSetConstantValues(hypre_ParCSRMatrixDiag(A), value);
1630 hypre_CSRMatrixSetConstantValues(hypre_ParCSRMatrixOffd(A), value);
1639 #endif // MFEM_USE_MPI
int index(int i, int j, int nx, int ny)