612 if ( A_r == NULL && A_i == NULL ) {
return NULL; }
616 HYPRE_BigInt global_num_rows = std::max(global_num_rows_r,
621 HYPRE_BigInt global_num_cols = std::max(global_num_cols_r,
624 int row_starts_size = (HYPRE_AssumedPartitionCheck()) ? 2 : nranks_ + 1;
631 ((A_i) ? A_i->
RowPart() : NULL);
633 ((A_i) ? A_i->
ColPart() : NULL);
635 for (
int i = 0; i < row_starts_size; i++)
637 row_starts[i] = 2 * row_starts_z[i];
638 col_starts[i] = 2 * col_starts_z[i];
644 int nrows_r = 0, nrows_i = 0, ncols_r = 0, ncols_i = 0;
645 int ncols_offd_r = 0, ncols_offd_i = 0;
650 nrows_r = diag_r.
Height();
651 ncols_r = diag_r.
Width();
652 ncols_offd_r = offd_r.
Width();
658 nrows_i =
diag_i.Height();
660 ncols_offd_i = offd_i.
Width();
662 int nrows = std::max(nrows_r, nrows_i);
663 int ncols = std::max(ncols_r, ncols_i);
666 std::set<HYPRE_BigInt> cset;
667 for (
int i=0; i<ncols_offd_r; i++)
669 cset.insert(cmap_r[i]);
671 for (
int i=0; i<ncols_offd_i; i++)
673 cset.insert(cmap_i[i]);
675 int num_cols_offd = (int)cset.size();
678 const int * diag_r_I = (A_r) ? diag_r.
GetI() : NULL;
679 const int * diag_i_I = (A_i) ?
diag_i.GetI() : NULL;
681 const int * diag_r_J = (A_r) ? diag_r.
GetJ() : NULL;
682 const int * diag_i_J = (A_i) ?
diag_i.GetJ() : NULL;
685 const real_t * diag_i_D = (A_i) ?
diag_i.GetData() : NULL;
687 int diag_r_nnz = (diag_r_I) ? diag_r_I[nrows] : 0;
688 int diag_i_nnz = (diag_i_I) ? diag_i_I[nrows] : 0;
689 int diag_nnz = 2 * (diag_r_nnz + diag_i_nnz);
692 const int * offd_r_I = (A_r) ? offd_r.
GetI() : NULL;
693 const int * offd_i_I = (A_i) ? offd_i.
GetI() : NULL;
695 const int * offd_r_J = (A_r) ? offd_r.
GetJ() : NULL;
696 const int * offd_i_J = (A_i) ? offd_i.
GetJ() : NULL;
701 int offd_r_nnz = (offd_r_I) ? offd_r_I[nrows] : 0;
702 int offd_i_nnz = (offd_i_I) ? offd_i_I[nrows] : 0;
703 int offd_nnz = 2 * (offd_r_nnz + offd_i_nnz);
706 HYPRE_Int * diag_I = mfem_hypre_CTAlloc_host(HYPRE_Int, 2 * nrows + 1);
707 HYPRE_Int * diag_J = mfem_hypre_CTAlloc_host(HYPRE_Int, diag_nnz);
708 real_t * diag_D = mfem_hypre_CTAlloc_host(
real_t, diag_nnz);
710 HYPRE_Int * offd_I = mfem_hypre_CTAlloc_host(HYPRE_Int, 2 * nrows + 1);
711 HYPRE_Int * offd_J = mfem_hypre_CTAlloc_host(HYPRE_Int, offd_nnz);
712 real_t * offd_D = mfem_hypre_CTAlloc_host(
real_t, offd_nnz);
720 diag_I[nrows] = diag_r_nnz + diag_i_nnz;
721 for (
int i=0; i<nrows; i++)
723 diag_I[i + 1] = ((diag_r_I)?diag_r_I[i+1]:0) +
724 ((diag_i_I)?diag_i_I[i+1]:0);
725 diag_I[i + nrows + 1] = diag_I[i+1] + diag_r_nnz + diag_i_nnz;
729 for (
int j=0; j<diag_r_I[i+1] - diag_r_I[i]; j++)
731 diag_J[diag_I[i] + j] = diag_r_J[diag_r_I[i] + j];
732 diag_D[diag_I[i] + j] = diag_r_D[diag_r_I[i] + j];
734 diag_J[diag_I[i+nrows] + j] =
735 diag_r_J[diag_r_I[i] + j] + ncols;
736 diag_D[diag_I[i+nrows] + j] =
737 factor * diag_r_D[diag_r_I[i] + j];
742 const int off_r = (diag_r_I)?(diag_r_I[i+1] - diag_r_I[i]):0;
743 for (
int j=0; j<diag_i_I[i+1] - diag_i_I[i]; j++)
745 diag_J[diag_I[i] + off_r + j] = diag_i_J[diag_i_I[i] + j] + ncols;
746 diag_D[diag_I[i] + off_r + j] = -diag_i_D[diag_i_I[i] + j];
748 diag_J[diag_I[i+nrows] + off_r + j] = diag_i_J[diag_i_I[i] + j];
749 diag_D[diag_I[i+nrows] + off_r + j] =
750 factor * diag_i_D[diag_i_I[i] + j];
756 int num_recv_procs = 0;
758 this->getColStartStop(A_r, A_i, num_recv_procs, offd_col_start_stop);
760 std::set<HYPRE_BigInt>::iterator sit;
761 std::map<HYPRE_BigInt,HYPRE_BigInt> cmapa, cmapb, cinvmap;
762 for (sit=cset.begin(); sit!=cset.end(); sit++)
767 for (
int i=0; i<num_recv_procs; i++)
769 if (offd_col_start_stop[2*i] <= col_orig &&
770 col_orig < offd_col_start_stop[2*i+1])
772 col_2x2 = offd_col_start_stop[2*i] + col_orig;
773 col_size = offd_col_start_stop[2*i+1] - offd_col_start_stop[2*i];
777 cmapa[*sit] = col_2x2;
778 cmapb[*sit] = col_2x2 + col_size;
779 cinvmap[col_2x2] = -1;
780 cinvmap[col_2x2 + col_size] = -1;
782 delete [] offd_col_start_stop;
785 std::map<HYPRE_BigInt, HYPRE_BigInt>::iterator mit;
787 for (mit=cinvmap.begin(); mit!=cinvmap.end(); mit++, i++)
790 cmap[i] = mit->first;
796 offd_I[nrows] = offd_r_nnz + offd_i_nnz;
797 for (
int i=0; i<nrows; i++)
799 offd_I[i + 1] = ((offd_r_I)?offd_r_I[i+1]:0) +
800 ((offd_i_I)?offd_i_I[i+1]:0);
801 offd_I[i + nrows + 1] = offd_I[i+1] + offd_r_nnz + offd_i_nnz;
805 const int off_i = (offd_i_I)?(offd_i_I[i+1] - offd_i_I[i]):0;
806 for (
int j=0; j<offd_r_I[i+1] - offd_r_I[i]; j++)
808 offd_J[offd_I[i] + j] =
809 cinvmap[cmapa[cmap_r[offd_r_J[offd_r_I[i] + j]]]];
810 offd_D[offd_I[i] + j] = offd_r_D[offd_r_I[i] + j];
812 offd_J[offd_I[i+nrows] + off_i + j] =
813 cinvmap[cmapb[cmap_r[offd_r_J[offd_r_I[i] + j]]]];
814 offd_D[offd_I[i+nrows] + off_i + j] =
815 factor * offd_r_D[offd_r_I[i] + j];
820 const int off_r = (offd_r_I)?(offd_r_I[i+1] - offd_r_I[i]):0;
821 for (
int j=0; j<offd_i_I[i+1] - offd_i_I[i]; j++)
823 offd_J[offd_I[i] + off_r + j] =
824 cinvmap[cmapb[cmap_i[offd_i_J[offd_i_I[i] + j]]]];
825 offd_D[offd_I[i] + off_r + j] = -offd_i_D[offd_i_I[i] + j];
827 offd_J[offd_I[i+nrows] + j] =
828 cinvmap[cmapa[cmap_i[offd_i_J[offd_i_I[i] + j]]]];
829 offd_D[offd_I[i+nrows] + j] = factor * offd_i_D[offd_i_I[i] + j];
838 row_starts, col_starts,
839 diag_I, diag_J, diag_D,
840 offd_I, offd_J, offd_D,
841 2 * num_cols_offd, cmap,
844#if MFEM_HYPRE_VERSION <= 22200
846 hypre_ParCSRMatrix *hA = (hypre_ParCSRMatrix*)(*A);
848 hypre_ParCSRMatrixSetRowStartsOwner(hA,1);
849 hypre_ParCSRMatrixSetColStartsOwner(hA,1);
851 mfem_hypre_TFree_host(row_starts);
852 mfem_hypre_TFree_host(col_starts);