560 if ( A_r == NULL && A_i == NULL ) {
return NULL; }
564 HYPRE_BigInt global_num_rows = std::max(global_num_rows_r,
569 HYPRE_BigInt global_num_cols = std::max(global_num_cols_r,
572 int row_starts_size = (HYPRE_AssumedPartitionCheck()) ? 2 : nranks_ + 1;
579 ((A_i) ? A_i->
RowPart() : NULL);
581 ((A_i) ? A_i->
ColPart() : NULL);
583 for (
int i = 0; i < row_starts_size; i++)
585 row_starts[i] = 2 * row_starts_z[i];
586 col_starts[i] = 2 * col_starts_z[i];
592 int nrows_r = 0, nrows_i = 0, ncols_r = 0, ncols_i = 0;
593 int ncols_offd_r = 0, ncols_offd_i = 0;
598 nrows_r = diag_r.
Height();
599 ncols_r = diag_r.
Width();
600 ncols_offd_r = offd_r.
Width();
606 nrows_i = diag_i.
Height();
607 ncols_i = diag_i.
Width();
608 ncols_offd_i = offd_i.
Width();
610 int nrows = std::max(nrows_r, nrows_i);
611 int ncols = std::max(ncols_r, ncols_i);
614 std::set<HYPRE_BigInt> cset;
615 for (
int i=0; i<ncols_offd_r; i++)
617 cset.insert(cmap_r[i]);
619 for (
int i=0; i<ncols_offd_i; i++)
621 cset.insert(cmap_i[i]);
623 int num_cols_offd = (int)cset.size();
626 const int * diag_r_I = (A_r) ? diag_r.
GetI() : NULL;
627 const int * diag_i_I = (A_i) ? diag_i.
GetI() : NULL;
629 const int * diag_r_J = (A_r) ? diag_r.
GetJ() : NULL;
630 const int * diag_i_J = (A_i) ? diag_i.
GetJ() : NULL;
635 int diag_r_nnz = (diag_r_I) ? diag_r_I[nrows] : 0;
636 int diag_i_nnz = (diag_i_I) ? diag_i_I[nrows] : 0;
637 int diag_nnz = 2 * (diag_r_nnz + diag_i_nnz);
640 const int * offd_r_I = (A_r) ? offd_r.
GetI() : NULL;
641 const int * offd_i_I = (A_i) ? offd_i.
GetI() : NULL;
643 const int * offd_r_J = (A_r) ? offd_r.
GetJ() : NULL;
644 const int * offd_i_J = (A_i) ? offd_i.
GetJ() : NULL;
649 int offd_r_nnz = (offd_r_I) ? offd_r_I[nrows] : 0;
650 int offd_i_nnz = (offd_i_I) ? offd_i_I[nrows] : 0;
651 int offd_nnz = 2 * (offd_r_nnz + offd_i_nnz);
654 HYPRE_Int * diag_I = mfem_hypre_CTAlloc_host(HYPRE_Int, 2 * nrows + 1);
655 HYPRE_Int * diag_J = mfem_hypre_CTAlloc_host(HYPRE_Int, diag_nnz);
656 real_t * diag_D = mfem_hypre_CTAlloc_host(
real_t, diag_nnz);
658 HYPRE_Int * offd_I = mfem_hypre_CTAlloc_host(HYPRE_Int, 2 * nrows + 1);
659 HYPRE_Int * offd_J = mfem_hypre_CTAlloc_host(HYPRE_Int, offd_nnz);
660 real_t * offd_D = mfem_hypre_CTAlloc_host(
real_t, offd_nnz);
668 diag_I[nrows] = diag_r_nnz + diag_i_nnz;
669 for (
int i=0; i<nrows; i++)
671 diag_I[i + 1] = ((diag_r_I)?diag_r_I[i+1]:0) +
672 ((diag_i_I)?diag_i_I[i+1]:0);
673 diag_I[i + nrows + 1] = diag_I[i+1] + diag_r_nnz + diag_i_nnz;
677 for (
int j=0; j<diag_r_I[i+1] - diag_r_I[i]; j++)
679 diag_J[diag_I[i] + j] = diag_r_J[diag_r_I[i] + j];
680 diag_D[diag_I[i] + j] = diag_r_D[diag_r_I[i] + j];
682 diag_J[diag_I[i+nrows] + j] =
683 diag_r_J[diag_r_I[i] + j] + ncols;
684 diag_D[diag_I[i+nrows] + j] =
685 factor * diag_r_D[diag_r_I[i] + j];
690 const int off_r = (diag_r_I)?(diag_r_I[i+1] - diag_r_I[i]):0;
691 for (
int j=0; j<diag_i_I[i+1] - diag_i_I[i]; j++)
693 diag_J[diag_I[i] + off_r + j] = diag_i_J[diag_i_I[i] + j] + ncols;
694 diag_D[diag_I[i] + off_r + j] = -diag_i_D[diag_i_I[i] + j];
696 diag_J[diag_I[i+nrows] + off_r + j] = diag_i_J[diag_i_I[i] + j];
697 diag_D[diag_I[i+nrows] + off_r + j] =
698 factor * diag_i_D[diag_i_I[i] + j];
704 int num_recv_procs = 0;
706 this->getColStartStop(A_r, A_i, num_recv_procs, offd_col_start_stop);
708 std::set<HYPRE_BigInt>::iterator sit;
709 std::map<HYPRE_BigInt,HYPRE_BigInt> cmapa, cmapb, cinvmap;
710 for (sit=cset.begin(); sit!=cset.end(); sit++)
715 for (
int i=0; i<num_recv_procs; i++)
717 if (offd_col_start_stop[2*i] <= col_orig &&
718 col_orig < offd_col_start_stop[2*i+1])
720 col_2x2 = offd_col_start_stop[2*i] + col_orig;
721 col_size = offd_col_start_stop[2*i+1] - offd_col_start_stop[2*i];
725 cmapa[*sit] = col_2x2;
726 cmapb[*sit] = col_2x2 + col_size;
727 cinvmap[col_2x2] = -1;
728 cinvmap[col_2x2 + col_size] = -1;
730 delete [] offd_col_start_stop;
733 std::map<HYPRE_BigInt, HYPRE_BigInt>::iterator mit;
735 for (mit=cinvmap.begin(); mit!=cinvmap.end(); mit++, i++)
738 cmap[i] = mit->first;
744 offd_I[nrows] = offd_r_nnz + offd_i_nnz;
745 for (
int i=0; i<nrows; i++)
747 offd_I[i + 1] = ((offd_r_I)?offd_r_I[i+1]:0) +
748 ((offd_i_I)?offd_i_I[i+1]:0);
749 offd_I[i + nrows + 1] = offd_I[i+1] + offd_r_nnz + offd_i_nnz;
753 const int off_i = (offd_i_I)?(offd_i_I[i+1] - offd_i_I[i]):0;
754 for (
int j=0; j<offd_r_I[i+1] - offd_r_I[i]; j++)
756 offd_J[offd_I[i] + j] =
757 cinvmap[cmapa[cmap_r[offd_r_J[offd_r_I[i] + j]]]];
758 offd_D[offd_I[i] + j] = offd_r_D[offd_r_I[i] + j];
760 offd_J[offd_I[i+nrows] + off_i + j] =
761 cinvmap[cmapb[cmap_r[offd_r_J[offd_r_I[i] + j]]]];
762 offd_D[offd_I[i+nrows] + off_i + j] =
763 factor * offd_r_D[offd_r_I[i] + j];
768 const int off_r = (offd_r_I)?(offd_r_I[i+1] - offd_r_I[i]):0;
769 for (
int j=0; j<offd_i_I[i+1] - offd_i_I[i]; j++)
771 offd_J[offd_I[i] + off_r + j] =
772 cinvmap[cmapb[cmap_i[offd_i_J[offd_i_I[i] + j]]]];
773 offd_D[offd_I[i] + off_r + j] = -offd_i_D[offd_i_I[i] + j];
775 offd_J[offd_I[i+nrows] + j] =
776 cinvmap[cmapa[cmap_i[offd_i_J[offd_i_I[i] + j]]]];
777 offd_D[offd_I[i+nrows] + j] = factor * offd_i_D[offd_i_I[i] + j];
786 row_starts, col_starts,
787 diag_I, diag_J, diag_D,
788 offd_I, offd_J, offd_D,
789 2 * num_cols_offd, cmap,
792#if MFEM_HYPRE_VERSION <= 22200
794 hypre_ParCSRMatrix *hA = (hypre_ParCSRMatrix*)(*A);
796 hypre_ParCSRMatrixSetRowStartsOwner(hA,1);
797 hypre_ParCSRMatrixSetColStartsOwner(hA,1);
799 mfem_hypre_TFree_host(row_starts);
800 mfem_hypre_TFree_host(col_starts);