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];
478 void hypre_ParCSRMatrixEliminateAAe(hypre_ParCSRMatrix *A,
479 hypre_ParCSRMatrix **Ae,
480 HYPRE_Int num_rowscols_to_elim,
481 HYPRE_Int *rowscols_to_elim)
485 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
486 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
487 HYPRE_Int A_diag_nrows = hypre_CSRMatrixNumRows(A_diag);
488 HYPRE_Int A_offd_ncols = hypre_CSRMatrixNumCols(A_offd);
490 *Ae = hypre_ParCSRMatrixCreate(hypre_ParCSRMatrixComm(A),
491 hypre_ParCSRMatrixGlobalNumRows(A),
492 hypre_ParCSRMatrixGlobalNumCols(A),
493 hypre_ParCSRMatrixRowStarts(A),
494 hypre_ParCSRMatrixColStarts(A),
497 hypre_ParCSRMatrixSetRowStartsOwner(*Ae, 0);
498 hypre_ParCSRMatrixSetColStartsOwner(*Ae, 0);
500 hypre_CSRMatrix *Ae_diag = hypre_ParCSRMatrixDiag(*Ae);
501 hypre_CSRMatrix *Ae_offd = hypre_ParCSRMatrixOffd(*Ae);
502 HYPRE_Int Ae_offd_ncols;
504 HYPRE_Int num_offd_cols_to_elim;
505 HYPRE_Int *offd_cols_to_elim;
507 HYPRE_Int *A_col_map_offd = hypre_ParCSRMatrixColMapOffd(A);
508 HYPRE_Int *Ae_col_map_offd;
511 HYPRE_Int *col_remap;
515 hypre_ParCSRCommHandle *comm_handle;
516 hypre_ParCSRCommPkg *comm_pkg;
517 HYPRE_Int num_sends, *int_buf_data;
518 HYPRE_Int index, start;
520 HYPRE_Int *eliminate_row = mfem_hypre_CTAlloc(HYPRE_Int, A_diag_nrows);
521 HYPRE_Int *eliminate_col = mfem_hypre_CTAlloc(HYPRE_Int, A_offd_ncols);
524 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
527 hypre_MatvecCommPkgCreate(A);
528 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
532 for (i = 0; i < A_diag_nrows; i++)
534 eliminate_row[i] = 0;
536 for (i = 0; i < num_rowscols_to_elim; i++)
538 eliminate_row[rowscols_to_elim[i]] = 1;
543 num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
544 int_buf_data = mfem_hypre_CTAlloc(
546 hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends));
548 for (i = 0; i < num_sends; i++)
550 start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
551 for (j = start; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++)
553 k = hypre_ParCSRCommPkgSendMapElmt(comm_pkg, j);
554 int_buf_data[index++] = eliminate_row[k];
557 comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg,
558 int_buf_data, eliminate_col);
561 hypre_CSRMatrixElimCreate(A_diag, Ae_diag,
562 num_rowscols_to_elim, rowscols_to_elim,
563 num_rowscols_to_elim, rowscols_to_elim,
566 hypre_CSRMatrixEliminateRowsCols(A_diag, Ae_diag,
567 num_rowscols_to_elim, rowscols_to_elim,
568 num_rowscols_to_elim, rowscols_to_elim,
570 hypre_CSRMatrixReorder(Ae_diag);
573 hypre_ParCSRCommHandleDestroy(comm_handle);
576 num_offd_cols_to_elim = 0;
577 for (i = 0; i < A_offd_ncols; i++)
579 if (eliminate_col[i]) { num_offd_cols_to_elim++; }
582 offd_cols_to_elim = mfem_hypre_CTAlloc(HYPRE_Int, num_offd_cols_to_elim);
585 num_offd_cols_to_elim = 0;
586 for (i = 0; i < A_offd_ncols; i++)
588 if (eliminate_col[i])
590 offd_cols_to_elim[num_offd_cols_to_elim++] = i;
594 mfem_hypre_TFree(int_buf_data);
595 mfem_hypre_TFree(eliminate_col);
596 mfem_hypre_TFree(eliminate_row);
600 col_mark = mfem_hypre_CTAlloc(HYPRE_Int, A_offd_ncols);
601 col_remap = mfem_hypre_CTAlloc(HYPRE_Int, A_offd_ncols);
603 hypre_CSRMatrixElimCreate(A_offd, Ae_offd,
604 num_rowscols_to_elim, rowscols_to_elim,
605 num_offd_cols_to_elim, offd_cols_to_elim,
608 for (i = k = 0; i < A_offd_ncols; i++)
610 if (col_mark[i]) { col_remap[i] = k++; }
613 hypre_CSRMatrixEliminateRowsCols(A_offd, Ae_offd,
614 num_rowscols_to_elim, rowscols_to_elim,
615 num_offd_cols_to_elim, offd_cols_to_elim,
620 for (i = 0; i < A_offd_ncols; i++)
622 if (col_mark[i]) { Ae_offd_ncols++; }
625 Ae_col_map_offd = mfem_hypre_CTAlloc(HYPRE_Int, Ae_offd_ncols);
628 for (i = 0; i < A_offd_ncols; i++)
632 Ae_col_map_offd[Ae_offd_ncols++] = A_col_map_offd[i];
636 hypre_ParCSRMatrixColMapOffd(*Ae) = Ae_col_map_offd;
637 hypre_CSRMatrixNumCols(Ae_offd) = Ae_offd_ncols;
639 mfem_hypre_TFree(col_remap);
640 mfem_hypre_TFree(col_mark);
641 mfem_hypre_TFree(offd_cols_to_elim);
643 hypre_ParCSRMatrixSetNumNonzeros(*Ae);
644 hypre_MatvecCommPkgCreate(*Ae);
652 void hypre_CSRMatrixSplit(hypre_CSRMatrix *A,
653 HYPRE_Int nr, HYPRE_Int nc,
654 HYPRE_Int *row_block_num, HYPRE_Int *col_block_num,
655 hypre_CSRMatrix **blocks)
657 HYPRE_Int i, j, k, bi, bj;
659 HYPRE_Int* A_i = hypre_CSRMatrixI(A);
660 HYPRE_Int* A_j = hypre_CSRMatrixJ(A);
661 HYPRE_Complex* A_data = hypre_CSRMatrixData(A);
663 HYPRE_Int A_rows = hypre_CSRMatrixNumRows(A);
664 HYPRE_Int A_cols = hypre_CSRMatrixNumCols(A);
666 HYPRE_Int *num_rows = mfem_hypre_CTAlloc(HYPRE_Int, nr);
667 HYPRE_Int *num_cols = mfem_hypre_CTAlloc(HYPRE_Int, nc);
669 HYPRE_Int *block_row = mfem_hypre_TAlloc(HYPRE_Int, A_rows);
670 HYPRE_Int *block_col = mfem_hypre_TAlloc(HYPRE_Int, A_cols);
672 for (i = 0; i < A_rows; i++)
674 block_row[i] = num_rows[row_block_num[i]]++;
676 for (j = 0; j < A_cols; j++)
678 block_col[j] = num_cols[col_block_num[j]]++;
682 for (i = 0; i < nr; i++)
684 for (j = 0; j < nc; j++)
686 hypre_CSRMatrix *B = hypre_CSRMatrixCreate(num_rows[i], num_cols[j], 0);
687 hypre_CSRMatrixI(B) = mfem_hypre_CTAlloc(HYPRE_Int, num_rows[i] + 1);
688 blocks[i*nc + j] = B;
693 for (i = 0; i < A_rows; i++)
695 bi = row_block_num[i];
696 for (j = A_i[i]; j < A_i[i+1]; j++)
698 bj = col_block_num[A_j[j]];
699 hypre_CSRMatrix *B = blocks[bi*nc + bj];
700 hypre_CSRMatrixI(B)[block_row[i] + 1]++;
705 for (k = 0; k < nr*nc; k++)
707 hypre_CSRMatrix *B = blocks[k];
708 HYPRE_Int* B_i = hypre_CSRMatrixI(B);
710 HYPRE_Int nnz = 0, rs;
711 for (
int k = 1; k <= hypre_CSRMatrixNumRows(B); k++)
713 rs = B_i[k], B_i[k] = nnz, nnz += rs;
716 hypre_CSRMatrixJ(B) = mfem_hypre_TAlloc(HYPRE_Int, nnz);
717 hypre_CSRMatrixData(B) = mfem_hypre_TAlloc(HYPRE_Complex, nnz);
718 hypre_CSRMatrixNumNonzeros(B) = nnz;
722 for (i = 0; i < A_rows; i++)
724 bi = row_block_num[i];
725 for (j = A_i[i]; j < A_i[i+1]; j++)
728 bj = col_block_num[k];
729 hypre_CSRMatrix *B = blocks[bi*nc + bj];
730 HYPRE_Int *bii = hypre_CSRMatrixI(B) + block_row[i] + 1;
731 hypre_CSRMatrixJ(B)[*bii] = block_col[k];
732 hypre_CSRMatrixData(B)[*bii] = A_data[j];
737 mfem_hypre_TFree(block_col);
738 mfem_hypre_TFree(block_row);
740 mfem_hypre_TFree(num_cols);
741 mfem_hypre_TFree(num_rows);
745 void hypre_ParCSRMatrixSplit(hypre_ParCSRMatrix *A,
746 HYPRE_Int nr, HYPRE_Int nc,
747 hypre_ParCSRMatrix **blocks,
748 int interleaved_rows,
int interleaved_cols)
752 MPI_Comm comm = hypre_ParCSRMatrixComm(A);
754 hypre_CSRMatrix *Adiag = hypre_ParCSRMatrixDiag(A);
755 hypre_CSRMatrix *Aoffd = hypre_ParCSRMatrixOffd(A);
757 HYPRE_Int global_rows = hypre_ParCSRMatrixGlobalNumRows(A);
758 HYPRE_Int global_cols = hypre_ParCSRMatrixGlobalNumCols(A);
760 HYPRE_Int local_rows = hypre_CSRMatrixNumRows(Adiag);
761 HYPRE_Int local_cols = hypre_CSRMatrixNumCols(Adiag);
762 HYPRE_Int offd_cols = hypre_CSRMatrixNumCols(Aoffd);
764 hypre_assert(local_rows % nr == 0 && local_cols % nc == 0);
765 hypre_assert(global_rows % nr == 0 && global_cols % nc == 0);
767 HYPRE_Int block_rows = local_rows / nr;
768 HYPRE_Int block_cols = local_cols / nc;
769 HYPRE_Int num_blocks = nr * nc;
772 HYPRE_Int *row_block_num = mfem_hypre_TAlloc(HYPRE_Int, local_rows);
773 HYPRE_Int *col_block_num = mfem_hypre_TAlloc(HYPRE_Int, local_cols);
775 for (i = 0; i < local_rows; i++)
777 row_block_num[i] = interleaved_rows ? (i % nr) : (i / block_rows);
779 for (i = 0; i < local_cols; i++)
781 col_block_num[i] = interleaved_cols ? (i % nc) : (i / block_cols);
785 HYPRE_Int* offd_col_block_num = mfem_hypre_TAlloc(HYPRE_Int, offd_cols);
786 hypre_ParCSRCommHandle *comm_handle;
787 HYPRE_Int *int_buf_data;
790 hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg(A);
793 hypre_MatvecCommPkgCreate(A);
794 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
798 HYPRE_Int *count = mfem_hypre_CTAlloc(HYPRE_Int, nc);
799 HYPRE_Int *block_global_col = mfem_hypre_TAlloc(HYPRE_Int, local_cols);
800 HYPRE_Int first_col = hypre_ParCSRMatrixFirstColDiag(A) / nc;
801 for (i = 0; i < local_cols; i++)
803 block_global_col[i] = first_col + count[col_block_num[i]]++;
805 mfem_hypre_TFree(count);
808 HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
809 int_buf_data = mfem_hypre_CTAlloc(
811 hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends));
812 HYPRE_Int start, index = 0;
813 for (i = 0; i < num_sends; i++)
815 start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
816 for (j = start; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++)
818 k = hypre_ParCSRCommPkgSendMapElmt(comm_pkg, j);
819 int_buf_data[index++] = col_block_num[k] + nc*block_global_col[k];
822 mfem_hypre_TFree(block_global_col);
824 comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data,
829 HYPRE_Int num_procs = 1;
830 if (!hypre_ParCSRMatrixAssumedPartition(A))
832 hypre_MPI_Comm_size(comm, &num_procs);
835 HYPRE_Int *row_starts = mfem_hypre_TAlloc(HYPRE_Int, num_procs+1);
836 HYPRE_Int *col_starts = mfem_hypre_TAlloc(HYPRE_Int, num_procs+1);
837 for (i = 0; i <= num_procs; i++)
839 row_starts[i] = hypre_ParCSRMatrixRowStarts(A)[i] / nr;
840 col_starts[i] = hypre_ParCSRMatrixColStarts(A)[i] / nc;
843 for (i = 0; i < num_blocks; i++)
845 blocks[i] = hypre_ParCSRMatrixCreate(comm,
846 global_rows/nr, global_cols/nc,
847 row_starts, col_starts, 0, 0, 0);
851 hypre_CSRMatrix **csr_blocks = mfem_hypre_TAlloc(hypre_CSRMatrix*, nr*nc);
852 hypre_CSRMatrixSplit(Adiag, nr, nc, row_block_num, col_block_num,
855 for (i = 0; i < num_blocks; i++)
857 mfem_hypre_TFree(hypre_ParCSRMatrixDiag(blocks[i]));
858 hypre_ParCSRMatrixDiag(blocks[i]) = csr_blocks[i];
862 hypre_ParCSRCommHandleDestroy(comm_handle);
863 mfem_hypre_TFree(int_buf_data);
866 HYPRE_Int* offd_global_col = mfem_hypre_TAlloc(HYPRE_Int, offd_cols);
867 for (i = 0; i < offd_cols; i++)
869 offd_global_col[i] = offd_col_block_num[i] / nc;
870 offd_col_block_num[i] %= nc;
874 hypre_CSRMatrixSplit(Aoffd, nr, nc, row_block_num, offd_col_block_num,
877 for (i = 0; i < num_blocks; i++)
879 mfem_hypre_TFree(hypre_ParCSRMatrixOffd(blocks[i]));
880 hypre_ParCSRMatrixOffd(blocks[i]) = csr_blocks[i];
883 mfem_hypre_TFree(csr_blocks);
884 mfem_hypre_TFree(col_block_num);
885 mfem_hypre_TFree(row_block_num);
888 for (
int bi = 0; bi < nr; bi++)
890 for (
int bj = 0; bj < nc; bj++)
892 hypre_ParCSRMatrix *block = blocks[bi*nc + bj];
893 hypre_CSRMatrix *block_offd = hypre_ParCSRMatrixOffd(block);
894 HYPRE_Int block_offd_cols = hypre_CSRMatrixNumCols(block_offd);
896 HYPRE_Int *block_col_map = mfem_hypre_TAlloc(HYPRE_Int,
898 for (i = j = 0; i < offd_cols; i++)
900 HYPRE_Int bn = offd_col_block_num[i];
901 if (bn == bj) { block_col_map[j++] = offd_global_col[i]; }
903 hypre_assert(j == block_offd_cols);
905 hypre_ParCSRMatrixColMapOffd(block) = block_col_map;
909 mfem_hypre_TFree(offd_global_col);
910 mfem_hypre_TFree(offd_col_block_num);
913 for (i = 0; i < num_blocks; i++)
915 hypre_ParCSRMatrixSetNumNonzeros(blocks[i]);
916 hypre_MatvecCommPkgCreate(blocks[i]);
918 hypre_ParCSRMatrixOwnsData(blocks[i]) = 1;
921 hypre_ParCSRMatrixOwnsRowStarts(blocks[i]) = !i;
922 hypre_ParCSRMatrixOwnsColStarts(blocks[i]) = !i;
927 void hypre_CSRMatrixBooleanMatvec(hypre_CSRMatrix *A,
934 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
935 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
936 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A);
938 HYPRE_Int *A_rownnz = hypre_CSRMatrixRownnz(A);
939 HYPRE_Int num_rownnz = hypre_CSRMatrixNumRownnz(A);
941 HYPRE_Bool *x_data = x;
942 HYPRE_Bool *y_data = y;
944 HYPRE_Bool temp, tempx;
958 #ifdef HYPRE_USING_OPENMP
959 #pragma omp parallel for private(i) HYPRE_SMP_SCHEDULE
961 for (i = 0; i < num_rows; i++)
963 y_data[i] = y_data[i] && beta;
974 #ifdef HYPRE_USING_OPENMP
975 #pragma omp parallel for private(i) HYPRE_SMP_SCHEDULE
977 for (i = 0; i < num_rows; i++)
993 if (num_rownnz < xpar*(num_rows))
995 #ifdef HYPRE_USING_OPENMP
996 #pragma omp parallel for private(i,jj,m,tempx) HYPRE_SMP_SCHEDULE
998 for (i = 0; i < num_rownnz; i++)
1003 for (jj = A_i[m]; jj < A_i[m+1]; jj++)
1006 tempx = tempx || x_data[A_j[jj]];
1008 y_data[m] = y_data[m] || tempx;
1013 #ifdef HYPRE_USING_OPENMP
1014 #pragma omp parallel for private(i,jj,temp) HYPRE_SMP_SCHEDULE
1016 for (i = 0; i < num_rows; i++)
1019 for (jj = A_i[i]; jj < A_i[i+1]; jj++)
1022 temp = temp || x_data[A_j[jj]];
1024 y_data[i] = y_data[i] || temp;
1035 void hypre_CSRMatrixBooleanMatvecT(hypre_CSRMatrix *A,
1042 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
1043 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
1044 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A);
1045 HYPRE_Int num_cols = hypre_CSRMatrixNumCols(A);
1047 HYPRE_Bool *x_data = x;
1048 HYPRE_Bool *y_data = y;
1058 for (i = 0; i < num_cols; i++)
1082 for (i = 0; i < num_rows; i++)
1086 for (jj = A_i[i]; jj < A_i[i+1]; jj++)
1098 hypre_ParCSRCommHandle *
1099 hypre_ParCSRCommHandleCreate_bool(HYPRE_Int job,
1100 hypre_ParCSRCommPkg *comm_pkg,
1101 HYPRE_Bool *send_data,
1102 HYPRE_Bool *recv_data)
1104 HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
1105 HYPRE_Int num_recvs = hypre_ParCSRCommPkgNumRecvs(comm_pkg);
1106 MPI_Comm comm = hypre_ParCSRCommPkgComm(comm_pkg);
1108 hypre_ParCSRCommHandle *comm_handle;
1109 HYPRE_Int num_requests;
1110 hypre_MPI_Request *requests;
1113 HYPRE_Int my_id, num_procs;
1114 HYPRE_Int ip, vec_start, vec_len;
1116 num_requests = num_sends + num_recvs;
1117 requests = mfem_hypre_CTAlloc(hypre_MPI_Request, num_requests);
1119 hypre_MPI_Comm_size(comm, &num_procs);
1120 hypre_MPI_Comm_rank(comm, &my_id);
1127 HYPRE_Bool *d_send_data = (HYPRE_Bool *) send_data;
1128 HYPRE_Bool *d_recv_data = (HYPRE_Bool *) recv_data;
1129 for (i = 0; i < num_recvs; i++)
1131 ip = hypre_ParCSRCommPkgRecvProc(comm_pkg, i);
1132 vec_start = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i);
1133 vec_len = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i+1)-vec_start;
1134 hypre_MPI_Irecv(&d_recv_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1135 ip, 0, comm, &requests[j++]);
1137 for (i = 0; i < num_sends; i++)
1139 vec_start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
1140 vec_len = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1)-vec_start;
1141 ip = hypre_ParCSRCommPkgSendProc(comm_pkg, i);
1142 hypre_MPI_Isend(&d_send_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1143 ip, 0, comm, &requests[j++]);
1149 HYPRE_Bool *d_send_data = (HYPRE_Bool *) send_data;
1150 HYPRE_Bool *d_recv_data = (HYPRE_Bool *) recv_data;
1151 for (i = 0; i < num_sends; i++)
1153 vec_start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
1154 vec_len = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1)-vec_start;
1155 ip = hypre_ParCSRCommPkgSendProc(comm_pkg, i);
1156 hypre_MPI_Irecv(&d_recv_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1157 ip, 0, comm, &requests[j++]);
1159 for (i = 0; i < num_recvs; i++)
1161 ip = hypre_ParCSRCommPkgRecvProc(comm_pkg, i);
1162 vec_start = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i);
1163 vec_len = hypre_ParCSRCommPkgRecvVecStart(comm_pkg, i+1)-vec_start;
1164 hypre_MPI_Isend(&d_send_data[vec_start], vec_len, HYPRE_MPI_BOOL,
1165 ip, 0, comm, &requests[j++]);
1174 comm_handle = mfem_hypre_CTAlloc(hypre_ParCSRCommHandle, 1);
1176 hypre_ParCSRCommHandleCommPkg(comm_handle) = comm_pkg;
1177 hypre_ParCSRCommHandleSendData(comm_handle) = send_data;
1178 hypre_ParCSRCommHandleRecvData(comm_handle) = recv_data;
1179 hypre_ParCSRCommHandleNumRequests(comm_handle) = num_requests;
1180 hypre_ParCSRCommHandleRequests(comm_handle) = requests;
1186 void hypre_ParCSRMatrixBooleanMatvec(hypre_ParCSRMatrix *A,
1192 hypre_ParCSRCommHandle *comm_handle;
1193 hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg(A);
1194 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
1195 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
1197 HYPRE_Int num_cols_offd = hypre_CSRMatrixNumCols(offd);
1198 HYPRE_Int num_sends, i, j, index;
1200 HYPRE_Bool *x_tmp, *x_buf;
1202 x_tmp = mfem_hypre_CTAlloc(HYPRE_Bool, num_cols_offd);
1210 hypre_MatvecCommPkgCreate(A);
1211 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
1214 num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
1215 x_buf = mfem_hypre_CTAlloc(
1216 HYPRE_Bool, hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends));
1219 for (i = 0; i < num_sends; i++)
1221 j = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i);
1222 for ( ; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++)
1224 x_buf[index++] = x[hypre_ParCSRCommPkgSendMapElmt(comm_pkg, j)];
1228 comm_handle = hypre_ParCSRCommHandleCreate_bool(1, comm_pkg, x_buf, x_tmp);
1230 hypre_CSRMatrixBooleanMatvec(diag, alpha, x, beta, y);
1232 hypre_ParCSRCommHandleDestroy(comm_handle);
1236 hypre_CSRMatrixBooleanMatvec(offd, alpha, x_tmp, 1, y);
1239 mfem_hypre_TFree(x_buf);
1240 mfem_hypre_TFree(x_tmp);
1244 void hypre_ParCSRMatrixBooleanMatvecT(hypre_ParCSRMatrix *A,
1250 hypre_ParCSRCommHandle *comm_handle;
1251 hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg(A);
1252 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
1253 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
1257 HYPRE_Int num_cols_offd = hypre_CSRMatrixNumCols(offd);
1259 HYPRE_Int i, j, jj, end, num_sends;
1261 y_tmp = mfem_hypre_TAlloc(HYPRE_Bool, num_cols_offd);
1269 hypre_MatvecCommPkgCreate(A);
1270 comm_pkg = hypre_ParCSRMatrixCommPkg(A);
1273 num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
1274 y_buf = mfem_hypre_CTAlloc(
1275 HYPRE_Bool, hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends));
1279 #if MFEM_HYPRE_VERSION >= 21100
1283 hypre_CSRMatrixBooleanMatvec(A->offdT, alpha, x, 0, y_tmp);
1288 hypre_CSRMatrixBooleanMatvecT(offd, alpha, x, 0, y_tmp);
1292 comm_handle = hypre_ParCSRCommHandleCreate_bool(2, comm_pkg, y_tmp, y_buf);
1294 #if MFEM_HYPRE_VERSION >= 21100
1298 hypre_CSRMatrixBooleanMatvec(A->diagT, alpha, x, beta, y);
1303 hypre_CSRMatrixBooleanMatvecT(diag, alpha, x, beta, y);
1306 hypre_ParCSRCommHandleDestroy(comm_handle);
1308 for (i = 0; i < num_sends; i++)
1310 end = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1);
1311 for (j = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i); j < end; j++)
1313 jj = hypre_ParCSRCommPkgSendMapElmt(comm_pkg, j);
1314 y[jj] = y[jj] || y_buf[j];
1318 mfem_hypre_TFree(y_buf);
1319 mfem_hypre_TFree(y_tmp);
1323 hypre_CSRMatrixSum(hypre_CSRMatrix *A,
1327 HYPRE_Complex *A_data = hypre_CSRMatrixData(A);
1328 HYPRE_Int *A_i = hypre_CSRMatrixI(A);
1329 HYPRE_Int *A_j = hypre_CSRMatrixJ(A);
1330 HYPRE_Int nrows_A = hypre_CSRMatrixNumRows(A);
1331 HYPRE_Int ncols_A = hypre_CSRMatrixNumCols(A);
1332 HYPRE_Complex *B_data = hypre_CSRMatrixData(B);
1333 HYPRE_Int *B_i = hypre_CSRMatrixI(B);
1334 HYPRE_Int *B_j = hypre_CSRMatrixJ(B);
1335 HYPRE_Int nrows_B = hypre_CSRMatrixNumRows(B);
1336 HYPRE_Int ncols_B = hypre_CSRMatrixNumCols(B);
1338 HYPRE_Int ia, j, pos;
1341 if (nrows_A != nrows_B || ncols_A != ncols_B)
1346 marker = mfem_hypre_CTAlloc(HYPRE_Int, ncols_A);
1347 for (ia = 0; ia < ncols_A; ia++)
1352 for (ia = 0; ia < nrows_A; ia++)
1354 for (j = A_i[ia]; j < A_i[ia+1]; j++)
1359 for (j = B_i[ia]; j < B_i[ia+1]; j++)
1361 pos = marker[B_j[j]];
1366 A_data[pos] += beta * B_data[j];
1370 mfem_hypre_TFree(marker);
1374 hypre_ParCSRMatrix *
1375 hypre_ParCSRMatrixAdd(hypre_ParCSRMatrix *A,
1376 hypre_ParCSRMatrix *B)
1378 MPI_Comm comm = hypre_ParCSRMatrixComm(A);
1379 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
1380 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
1381 HYPRE_Int *A_cmap = hypre_ParCSRMatrixColMapOffd(A);
1382 HYPRE_Int A_cmap_size = hypre_CSRMatrixNumCols(A_offd);
1383 hypre_CSRMatrix *B_diag = hypre_ParCSRMatrixDiag(B);
1384 hypre_CSRMatrix *B_offd = hypre_ParCSRMatrixOffd(B);
1385 HYPRE_Int *B_cmap = hypre_ParCSRMatrixColMapOffd(B);
1386 HYPRE_Int B_cmap_size = hypre_CSRMatrixNumCols(B_offd);
1387 hypre_ParCSRMatrix *C;
1388 hypre_CSRMatrix *C_diag;
1389 hypre_CSRMatrix *C_offd;
1392 HYPRE_Int cmap_differ;
1396 if (A_cmap_size != B_cmap_size)
1402 for (im = 0; im < A_cmap_size; im++)
1404 if (A_cmap[im] != B_cmap[im])
1412 if ( cmap_differ == 0 )
1419 C_diag = hypre_CSRMatrixAdd(A_diag, B_diag);
1424 C_offd = hypre_CSRMatrixAdd(A_offd, B_offd);
1427 hypre_CSRMatrixDestroy(C_diag);
1431 C_cmap = mfem_hypre_TAlloc(HYPRE_Int, A_cmap_size);
1432 for (im = 0; im < A_cmap_size; im++)
1434 C_cmap[im] = A_cmap[im];
1437 C = hypre_ParCSRMatrixCreate(comm,
1438 hypre_ParCSRMatrixGlobalNumRows(A),
1439 hypre_ParCSRMatrixGlobalNumCols(A),
1440 hypre_ParCSRMatrixRowStarts(A),
1441 hypre_ParCSRMatrixColStarts(A),
1442 hypre_CSRMatrixNumCols(C_offd),
1443 hypre_CSRMatrixNumNonzeros(C_diag),
1444 hypre_CSRMatrixNumNonzeros(C_offd));
1448 hypre_CSRMatrixDestroy(hypre_ParCSRMatrixDiag(C));
1449 hypre_CSRMatrixDestroy(hypre_ParCSRMatrixOffd(C));
1450 hypre_ParCSRMatrixDiag(C) = C_diag;
1451 hypre_ParCSRMatrixOffd(C) = C_offd;
1453 hypre_ParCSRMatrixColMapOffd(C) = C_cmap;
1461 hypre_CSRMatrix * csr_A;
1462 hypre_CSRMatrix * csr_B;
1463 hypre_CSRMatrix * csr_C_temp;
1466 csr_A = hypre_MergeDiagAndOffd(A);
1469 csr_B = hypre_MergeDiagAndOffd(B);
1472 csr_C_temp = hypre_CSRMatrixAdd(csr_A,csr_B);
1475 ierr += hypre_CSRMatrixDestroy(csr_A);
1476 ierr += hypre_CSRMatrixDestroy(csr_B);
1479 C = hypre_ParCSRMatrixCreate(hypre_ParCSRMatrixComm(A),
1480 hypre_ParCSRMatrixGlobalNumRows(A),
1481 hypre_ParCSRMatrixGlobalNumCols(A),
1482 hypre_ParCSRMatrixRowStarts(A),
1483 hypre_ParCSRMatrixColStarts(A),
1490 ierr += GenerateDiagAndOffd(csr_C_temp, C,
1491 hypre_ParCSRMatrixFirstColDiag(A),
1492 hypre_ParCSRMatrixLastColDiag(A));
1495 ierr += hypre_CSRMatrixDestroy(csr_C_temp);
1497 MFEM_VERIFY(ierr == 0,
"");
1503 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(C));
1506 hypre_ParCSRMatrixSetDataOwner(C, 1);
1508 hypre_ParCSRMatrixSetRowStartsOwner(C, 0);
1509 hypre_ParCSRMatrixSetColStartsOwner(C, 0);
1515 hypre_ParCSRMatrixSum(hypre_ParCSRMatrix *A,
1517 hypre_ParCSRMatrix *B)
1519 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
1520 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
1521 hypre_CSRMatrix *B_diag = hypre_ParCSRMatrixDiag(B);
1522 hypre_CSRMatrix *B_offd = hypre_ParCSRMatrixOffd(B);
1523 HYPRE_Int ncols_B_offd = hypre_CSRMatrixNumCols(B_offd);
1526 error = hypre_CSRMatrixSum(A_diag, beta, B_diag);
1527 if (ncols_B_offd > 0)
1529 error = error ? error : hypre_CSRMatrixSum(A_offd, beta, B_offd);
1536 hypre_CSRMatrixSetConstantValues(hypre_CSRMatrix *A,
1537 HYPRE_Complex value)
1539 HYPRE_Complex *A_data = hypre_CSRMatrixData(A);
1540 HYPRE_Int A_nnz = hypre_CSRMatrixNumNonzeros(A);
1543 for (ia = 0; ia < A_nnz; ia++)
1552 hypre_ParCSRMatrixSetConstantValues(hypre_ParCSRMatrix *A,
1553 HYPRE_Complex value)
1555 hypre_CSRMatrixSetConstantValues(hypre_ParCSRMatrixDiag(A), value);
1556 hypre_CSRMatrixSetConstantValues(hypre_ParCSRMatrixOffd(A), value);
1565 #endif // MFEM_USE_MPI