12 #include "../config/config.hpp" 17 #include "../fem/fem.hpp" 18 #include "../general/forall.hpp" 32 #if MFEM_HYPRE_VERSION >= 21900 41 void Hypre::Finalize()
43 Hypre &hypre = Instance();
46 #if MFEM_HYPRE_VERSION >= 21900 49 hypre.finalized =
true;
53 void Hypre::SetDefaultOptions()
58 #if MFEM_HYPRE_VERSION >= 22100 59 #ifdef HYPRE_USING_CUDA 61 HYPRE_SetSpGemmUseCusparse(0);
62 #elif defined(HYPRE_USING_HIP) 90 template<
typename TargetT,
typename SourceT>
91 static TargetT *DuplicateAs(
const SourceT *array,
int size,
92 bool cplusplus =
true)
94 TargetT *target_array = cplusplus ? (TargetT*) Memory<TargetT>(size)
95 : mfem_hypre_TAlloc_host(TargetT, size);
96 for (
int i = 0; i < size; i++)
98 target_array[i] = array[i];
107 template <
typename T>
112 if (src_d_mt == MemoryType::DEFAULT)
114 src_d_mt = MemoryManager::GetDualMemoryType(src_h_mt);
121 inline void HypreParVector::_SetDataAndSize_()
123 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
124 #if !defined(HYPRE_USING_GPU) 125 SetDataAndSize(hypre_VectorData(x_loc),
129 MemoryType mt = (hypre_VectorMemoryLocation(x_loc) == HYPRE_MEMORY_HOST
131 if (hypre_VectorData(x_loc) != NULL)
133 data.Wrap(hypre_VectorData(x_loc), size, mt,
false);
145 x = hypre_ParVectorCreate(comm,glob_size,col);
146 hypre_ParVectorInitialize(x);
147 #if MFEM_HYPRE_VERSION <= 22200 148 hypre_ParVectorSetPartitioningOwner(x,0);
151 hypre_ParVectorSetDataOwner(x,1);
152 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
162 x = hypre_ParVectorCreate(comm,glob_size,col);
163 hypre_ParVectorSetDataOwner(x,1);
164 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
165 hypre_SeqVectorSetDataOwner(x_loc,0);
166 #if MFEM_HYPRE_VERSION <= 22200 167 hypre_ParVectorSetPartitioningOwner(x,0);
170 hypre_VectorData(x_loc) = &tmp;
171 #ifdef HYPRE_USING_GPU 172 hypre_VectorMemoryLocation(x_loc) =
173 is_device_ptr ? HYPRE_MEMORY_DEVICE : HYPRE_MEMORY_HOST;
179 hypre_ParVectorInitialize(x);
181 hypre_VectorData(x_loc) = data_;
188 y.CreateCompatibleVector())
191 hypre_SeqVectorCopy(hypre_ParVectorLocalVector(y.x),
192 hypre_ParVectorLocalVector(x));
198 *
this = std::move(y);
206 x = hypre_ParVectorInDomainOf(const_cast<HypreParMatrix&>(A));
210 x = hypre_ParVectorInRangeOf(const_cast<HypreParMatrix&>(A));
218 x = (hypre_ParVector *) y;
227 hypre_ParVectorInitialize(x);
228 #if MFEM_HYPRE_VERSION <= 22200 229 hypre_ParVectorSetPartitioningOwner(x,0);
232 hypre_ParVectorSetDataOwner(x,1);
233 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
241 result.x = hypre_ParVectorCreate(x -> comm, x -> global_size,
243 hypre_ParVectorInitialize(result.x);
244 #if MFEM_HYPRE_VERSION <= 22200 245 hypre_ParVectorSetPartitioningOwner(result.x,0);
247 hypre_ParVectorSetDataOwner(result.x,1);
248 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(result.x),1);
249 result._SetDataAndSize_();
250 result.own_ParVector = 1;
257 if (own_ParVector) { hypre_ParVectorDestroy(x); }
261 own_ParVector = owner;
266 hypre_Vector *hv = hypre_ParVectorToVectorAll(*
this);
269 hypre_SeqVectorSetDataOwner(hv,0);
270 hypre_SeqVectorDestroy(hv);
297 const auto own_tmp = y.own_ParVector;
299 own_ParVector = own_tmp;
300 const auto x_tmp = y.x;
308 hypre_VectorData(hypre_ParVectorLocalVector(x)) = data_;
314 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
315 hypre_VectorData(x_loc) =
317 #ifdef HYPRE_USING_GPU 318 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
324 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
326 #ifdef HYPRE_USING_GPU 327 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
333 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
335 #ifdef HYPRE_USING_GPU 336 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
346 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
347 hypre_VectorData(x_loc) =
349 #ifdef HYPRE_USING_GPU 350 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
361 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
363 #ifdef HYPRE_USING_GPU 364 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
375 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
377 #ifdef HYPRE_USING_GPU 378 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
385 return hypre_ParVectorSetRandomValues(x,seed);
390 hypre_ParVectorPrint(x,fname);
397 hypre_ParVectorDestroy(x);
400 x = hypre_ParVectorRead(comm, fname);
401 own_ParVector =
true;
409 hypre_ParVectorDestroy(x);
416 return hypre_ParVectorInnerProd(*x, *y);
421 return hypre_ParVectorInnerProd(x, y);
430 double loc_norm = vec.
Norml1();
431 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
435 double loc_norm = vec*vec;
436 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
442 for (
int i = 0; i < vec.
Size(); i++)
444 sum += pow(fabs(vec(i)),
p);
446 MPI_Allreduce(&sum, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
447 norm = pow(norm, 1.0/
p);
452 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_MAX, comm);
474 template <
typename T>
509 template <
typename SrcT,
typename DstT>
517 MFEM_FORALL(i, capacity, dst_p[i] = src_p[i];);
521 void HypreParMatrix::Init()
526 diagOwner = offdOwner = colMapOwner = -1;
538 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
539 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
540 const int num_rows =
NumRows();
543 diag->i =
const_cast<HYPRE_Int*
>(mem_diag.
I.
Read(mc, num_rows+1));
544 diag->j =
const_cast<HYPRE_Int*
>(mem_diag.
J.
Read(mc, diag_nnz));
545 diag->data =
const_cast<double*
>(mem_diag.
data.
Read(mc, diag_nnz));
546 offd->i =
const_cast<HYPRE_Int*
>(mem_offd.
I.
Read(mc, num_rows+1));
547 offd->j =
const_cast<HYPRE_Int*
>(mem_offd.
J.
Read(mc, offd_nnz));
548 offd->data =
const_cast<double*
>(mem_offd.
data.
Read(mc, offd_nnz));
549 #if MFEM_HYPRE_VERSION >= 21800 550 decltype(diag->memory_location) ml =
552 diag->memory_location = ml;
553 offd->memory_location = ml;
559 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
560 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
561 const int num_rows =
NumRows();
564 diag->i = mem_diag.
I.
ReadWrite(mc, num_rows+1);
567 offd->i = mem_offd.
I.
ReadWrite(mc, num_rows+1);
570 #if MFEM_HYPRE_VERSION >= 21800 571 decltype(diag->memory_location) ml =
573 diag->memory_location = ml;
574 offd->memory_location = ml;
578 void HypreParMatrix::Write(
MemoryClass mc,
bool set_diag,
bool set_offd)
580 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
581 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
594 #if MFEM_HYPRE_VERSION >= 21800 595 decltype(diag->memory_location) ml =
597 if (set_diag) { diag->memory_location = ml; }
598 if (set_offd) { offd->memory_location = ml; }
616 #if MFEM_HYPRE_VERSION >= 21800 617 MemoryType diag_mt = (A->diag->memory_location == HYPRE_MEMORY_HOST
619 MemoryType offd_mt = (A->offd->memory_location == HYPRE_MEMORY_HOST
625 diagOwner = HypreCsrToMem(A->diag, diag_mt,
false, mem_diag);
626 offdOwner = HypreCsrToMem(A->offd, offd_mt,
false, mem_offd);
632 hypre_CSRMatrix *hypre_csr,
647 const int num_rows = csr->
Height();
649 hypre_csr->i =
const_cast<HYPRE_Int*
>(mem_csr.
I.
Read(hypre_mc, num_rows+1));
650 hypre_csr->j =
const_cast<HYPRE_Int*
>(mem_csr.
J.
Read(hypre_mc, nnz));
651 hypre_csr->data =
const_cast<double*
>(mem_csr.
data.
Read(hypre_mc, nnz));
654 "invalid state: host ownership for I and J differ!");
659 signed char HypreParMatrix::CopyBoolCSR(Table *bool_csr,
660 MemoryIJData &mem_csr,
661 hypre_CSRMatrix *hypre_csr)
666 CopyMemory(bool_csr->GetIMemory(), mem_csr.I, hypre_mc,
false);
667 CopyMemory(bool_csr->GetJMemory(), mem_csr.J, hypre_mc,
false);
673 const int num_rows = bool_csr->Size();
674 const int nnz = bool_csr->Size_of_connections();
677 for (
int i = 0; i < nnz; i++)
681 hypre_csr->i =
const_cast<HYPRE_Int*
>(mem_csr.I.Read(hypre_mc, num_rows+1));
682 hypre_csr->j =
const_cast<HYPRE_Int*
>(mem_csr.J.Read(hypre_mc, nnz));
683 hypre_csr->data =
const_cast<double*
>(mem_csr.data.Read(hypre_mc, nnz));
685 MFEM_ASSERT(mem_csr.I.OwnsHostPtr() == mem_csr.J.OwnsHostPtr(),
686 "invalid state: host ownership for I and J differ!");
687 return (mem_csr.I.OwnsHostPtr() ? 1 : 0) +
688 (mem_csr.data.OwnsHostPtr() ? 2 : 0);
694 static void CopyCSR_J(
const int nnz,
const MemoryIJData &mem_csr,
700 MFEM_FORALL(i, nnz, dst_p[i] = src_p[i];);
705 signed char HypreParMatrix::HypreCsrToMem(hypre_CSRMatrix *h_mat,
712 mem.I.Wrap(h_mat->i, nr1, h_mat_mt, own_ija);
713 mem.J.Wrap(h_mat->j, nnz, h_mat_mt, own_ija);
714 mem.data.Wrap(h_mat->data, nnz, h_mat_mt, own_ija);
720 h_mem.I.New(nr1, hypre_mt);
721 h_mem.I.CopyFrom(mem.I, nr1);
723 h_mem.J.New(nnz, hypre_mt);
724 h_mem.J.CopyFrom(mem.J, nnz);
726 h_mem.data.New(nnz, hypre_mt);
727 h_mem.data.CopyFrom(mem.data, nnz);
736 #if MFEM_HYPRE_VERSION < 21400 737 hypre_TFree(h_mat->i);
738 #elif MFEM_HYPRE_VERSION < 21800 739 hypre_TFree(h_mat->i, HYPRE_MEMORY_SHARED);
741 hypre_TFree(h_mat->i, h_mat->memory_location);
743 if (h_mat->owns_data)
745 #if MFEM_HYPRE_VERSION < 21400 746 hypre_TFree(h_mat->j);
747 hypre_TFree(h_mat->data);
748 #elif MFEM_HYPRE_VERSION < 21800 749 hypre_TFree(h_mat->j, HYPRE_MEMORY_SHARED);
750 hypre_TFree(h_mat->data, HYPRE_MEMORY_SHARED);
752 hypre_TFree(h_mat->j, h_mat->memory_location);
753 hypre_TFree(h_mat->data, h_mat->memory_location);
757 h_mat->i = mem.I.ReadWrite(hypre_mc, nr1);
758 h_mat->j = mem.J.ReadWrite(hypre_mc, nnz);
759 h_mat->data = mem.data.ReadWrite(hypre_mc, nnz);
760 h_mat->owns_data = 0;
761 #if MFEM_HYPRE_VERSION >= 21800 762 h_mat->memory_location = HYPRE_MEMORY_DEVICE;
772 :
Operator(diag->Height(), diag->Width())
775 A = hypre_ParCSRMatrixCreate(comm, glob_size, glob_size, row_starts,
777 hypre_ParCSRMatrixSetDataOwner(A,1);
778 #if MFEM_HYPRE_VERSION <= 22200 779 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
780 hypre_ParCSRMatrixSetColStartsOwner(A,0);
783 hypre_CSRMatrixSetDataOwner(A->diag,0);
784 diagOwner = CopyCSR(diag, mem_diag, A->diag,
false);
785 hypre_CSRMatrixSetRownnz(A->diag);
787 hypre_CSRMatrixSetDataOwner(A->offd,1);
788 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
796 hypre_ParCSRMatrixSetNumNonzeros(A);
800 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
804 CopyCSR_J(A->diag->num_nonzeros, mem_diag, diag->
GetMemoryJ());
808 hypre_MatvecCommPkgCreate(A);
818 :
Operator(diag->Height(), diag->Width())
821 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
822 row_starts, col_starts,
824 hypre_ParCSRMatrixSetDataOwner(A,1);
825 #if MFEM_HYPRE_VERSION <= 22200 826 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
827 hypre_ParCSRMatrixSetColStartsOwner(A,0);
830 hypre_CSRMatrixSetDataOwner(A->diag,0);
831 diagOwner = CopyCSR(diag, mem_diag, A->diag,
false);
832 hypre_CSRMatrixSetRownnz(A->diag);
834 hypre_CSRMatrixSetDataOwner(A->offd,1);
835 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
838 hypre_ParCSRMatrixSetNumNonzeros(A);
841 if (row_starts == col_starts)
844 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
848 CopyCSR_J(A->diag->num_nonzeros, mem_diag, diag->
GetMemoryJ());
853 hypre_MatvecCommPkgCreate(A);
866 :
Operator(diag->Height(), diag->Width())
869 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
870 row_starts, col_starts,
873 hypre_ParCSRMatrixSetDataOwner(A,1);
874 #if MFEM_HYPRE_VERSION <= 22200 875 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
876 hypre_ParCSRMatrixSetColStartsOwner(A,0);
879 hypre_CSRMatrixSetDataOwner(A->diag,0);
880 diagOwner = CopyCSR(diag, mem_diag, A->diag, own_diag_offd);
881 if (own_diag_offd) {
delete diag; }
882 hypre_CSRMatrixSetRownnz(A->diag);
884 hypre_CSRMatrixSetDataOwner(A->offd,0);
885 offdOwner = CopyCSR(offd, mem_offd, A->offd, own_diag_offd);
886 if (own_diag_offd) {
delete offd; }
887 hypre_CSRMatrixSetRownnz(A->offd);
889 hypre_ParCSRMatrixColMapOffd(A) = cmap;
893 hypre_ParCSRMatrixSetNumNonzeros(A);
896 if (row_starts == col_starts)
899 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
903 CopyCSR_J(A->diag->num_nonzeros, mem_diag, diag->
GetMemoryJ());
908 hypre_MatvecCommPkgCreate(A);
917 HYPRE_Int *diag_i, HYPRE_Int *diag_j,
double *diag_data,
918 HYPRE_Int *offd_i, HYPRE_Int *offd_j,
double *offd_data,
923 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
924 row_starts, col_starts, offd_num_cols, 0, 0);
925 hypre_ParCSRMatrixSetDataOwner(A,1);
926 #if MFEM_HYPRE_VERSION <= 22200 927 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
928 hypre_ParCSRMatrixSetColStartsOwner(A,0);
931 HYPRE_Int local_num_rows = hypre_CSRMatrixNumRows(A->diag);
933 hypre_CSRMatrixSetDataOwner(A->diag, hypre_arrays);
934 hypre_CSRMatrixI(A->diag) = diag_i;
935 hypre_CSRMatrixJ(A->diag) = diag_j;
936 hypre_CSRMatrixData(A->diag) = diag_data;
937 hypre_CSRMatrixNumNonzeros(A->diag) = diag_i[local_num_rows];
938 #ifdef HYPRE_USING_GPU 939 hypre_CSRMatrixMemoryLocation(A->diag) = HYPRE_MEMORY_HOST;
942 hypre_CSRMatrixSetDataOwner(A->offd, hypre_arrays);
943 hypre_CSRMatrixI(A->offd) = offd_i;
944 hypre_CSRMatrixJ(A->offd) = offd_j;
945 hypre_CSRMatrixData(A->offd) = offd_data;
946 hypre_CSRMatrixNumNonzeros(A->offd) = offd_i[local_num_rows];
947 #ifdef HYPRE_USING_GPU 948 hypre_CSRMatrixMemoryLocation(A->offd) = HYPRE_MEMORY_HOST;
951 hypre_ParCSRMatrixColMapOffd(A) = offd_col_map;
953 colMapOwner = hypre_arrays ? -1 : 1;
955 hypre_ParCSRMatrixSetNumNonzeros(A);
958 if (row_starts == col_starts)
960 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
963 hypre_MatvecCommPkgCreate(A);
971 diagOwner = HypreCsrToMem(A->diag, host_mt,
true, mem_diag);
972 offdOwner = HypreCsrToMem(A->offd, host_mt,
true, mem_offd);
977 diagOwner = HypreCsrToMem(A->diag, host_mt,
false, mem_diag);
978 offdOwner = HypreCsrToMem(A->offd, host_mt,
false, mem_offd);
982 hypre_CSRMatrixSetRownnz(A->diag);
983 hypre_CSRMatrixSetRownnz(A->offd);
992 MFEM_ASSERT(sm_a != NULL,
"invalid input");
993 MFEM_VERIFY(!HYPRE_AssumedPartitionCheck(),
994 "this method can not be used with assumed partition");
998 hypre_CSRMatrix *csr_a;
999 csr_a = hypre_CSRMatrixCreate(sm_a ->
Height(), sm_a ->
Width(),
1000 sm_a -> NumNonZeroElems());
1002 hypre_CSRMatrixSetDataOwner(csr_a,0);
1004 CopyCSR(sm_a, mem_a, csr_a,
false);
1005 hypre_CSRMatrixSetRownnz(csr_a);
1009 hypre_ParCSRMatrix *new_A =
1010 hypre_CSRMatrixToParCSRMatrix(comm, csr_a, row_starts, col_starts);
1016 hypre_CSRMatrixI(csr_a) = NULL;
1017 hypre_CSRMatrixDestroy(csr_a);
1020 if (row_starts == col_starts)
1022 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(new_A));
1025 hypre_MatvecCommPkgCreate(A);
1040 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
1041 row_starts, col_starts, 0, nnz, 0);
1042 hypre_ParCSRMatrixSetDataOwner(A,1);
1043 #if MFEM_HYPRE_VERSION <= 22200 1044 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
1045 hypre_ParCSRMatrixSetColStartsOwner(A,0);
1048 hypre_CSRMatrixSetDataOwner(A->diag,0);
1049 diagOwner = CopyBoolCSR(diag, mem_diag, A->diag);
1050 hypre_CSRMatrixSetRownnz(A->diag);
1052 hypre_CSRMatrixSetDataOwner(A->offd,1);
1053 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Size()+1);
1056 hypre_ParCSRMatrixSetNumNonzeros(A);
1059 if (row_starts == col_starts)
1062 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1069 hypre_MatvecCommPkgCreate(A);
1079 HYPRE_Int *i_diag, HYPRE_Int *j_diag,
1080 HYPRE_Int *i_offd, HYPRE_Int *j_offd,
1083 HYPRE_Int diag_nnz, offd_nnz;
1086 if (HYPRE_AssumedPartitionCheck())
1088 diag_nnz = i_diag[row[1]-row[0]];
1089 offd_nnz = i_offd[row[1]-row[0]];
1091 A = hypre_ParCSRMatrixCreate(comm, row[2], col[2], row, col,
1092 cmap_size, diag_nnz, offd_nnz);
1096 diag_nnz = i_diag[row[
id+1]-row[id]];
1097 offd_nnz = i_offd[row[
id+1]-row[id]];
1099 A = hypre_ParCSRMatrixCreate(comm, row[np], col[np], row, col,
1100 cmap_size, diag_nnz, offd_nnz);
1103 hypre_ParCSRMatrixSetDataOwner(A,1);
1104 #if MFEM_HYPRE_VERSION <= 22200 1105 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
1106 hypre_ParCSRMatrixSetColStartsOwner(A,0);
1110 for (HYPRE_Int i = 0; i < diag_nnz; i++)
1112 mem_diag.
data[i] = 1.0;
1116 for (HYPRE_Int i = 0; i < offd_nnz; i++)
1118 mem_offd.
data[i] = 1.0;
1121 hypre_CSRMatrixSetDataOwner(A->diag,0);
1122 hypre_CSRMatrixI(A->diag) = i_diag;
1123 hypre_CSRMatrixJ(A->diag) = j_diag;
1124 hypre_CSRMatrixData(A->diag) = mem_diag.
data;
1125 #ifdef HYPRE_USING_GPU 1126 hypre_CSRMatrixMemoryLocation(A->diag) = HYPRE_MEMORY_HOST;
1129 hypre_CSRMatrixSetDataOwner(A->offd,0);
1130 hypre_CSRMatrixI(A->offd) = i_offd;
1131 hypre_CSRMatrixJ(A->offd) = j_offd;
1132 hypre_CSRMatrixData(A->offd) = mem_offd.
data;
1133 #ifdef HYPRE_USING_GPU 1134 hypre_CSRMatrixMemoryLocation(A->offd) = HYPRE_MEMORY_HOST;
1137 hypre_ParCSRMatrixColMapOffd(A) = cmap;
1141 hypre_ParCSRMatrixSetNumNonzeros(A);
1146 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1149 hypre_MatvecCommPkgCreate(A);
1155 diagOwner = HypreCsrToMem(A->diag, host_mt,
true, mem_diag);
1156 offdOwner = HypreCsrToMem(A->offd, host_mt,
true, mem_offd);
1159 hypre_CSRMatrixSetRownnz(A->diag);
1160 hypre_CSRMatrixSetRownnz(A->offd);
1179 if (HYPRE_AssumedPartitionCheck())
1182 my_col_start = cols[0];
1183 my_col_end = cols[1];
1188 MPI_Comm_rank(comm, &myid);
1189 MPI_Comm_size(comm, &part_size);
1191 my_col_start = cols[myid];
1192 my_col_end = cols[myid+1];
1199 row_starts = col_starts = mfem_hypre_TAlloc_host(
HYPRE_BigInt, part_size);
1200 for (
int i = 0; i < part_size; i++)
1202 row_starts[i] = rows[i];
1207 row_starts = mfem_hypre_TAlloc_host(
HYPRE_BigInt, part_size);
1208 col_starts = mfem_hypre_TAlloc_host(
HYPRE_BigInt, part_size);
1209 for (
int i = 0; i < part_size; i++)
1211 row_starts[i] = rows[i];
1212 col_starts[i] = cols[i];
1218 HYPRE_Int diag_nnz = 0, offd_nnz = 0, offd_num_cols = 0;
1219 map<HYPRE_BigInt, HYPRE_Int> offd_map;
1220 for (HYPRE_Int j = 0, loc_nnz = I[nrows]; j < loc_nnz; j++)
1223 if (my_col_start <= glob_col && glob_col < my_col_end)
1229 offd_map.insert(pair<const HYPRE_BigInt, HYPRE_Int>(glob_col, -1));
1234 for (
auto it = offd_map.begin(); it != offd_map.end(); ++it)
1236 it->second = offd_num_cols++;
1240 A = hypre_ParCSRMatrixCreate(comm, glob_nrows, glob_ncols,
1241 row_starts, col_starts, offd_num_cols,
1242 diag_nnz, offd_nnz);
1243 hypre_ParCSRMatrixInitialize(A);
1249 HYPRE_Int *diag_i, *diag_j, *offd_i, *offd_j;
1251 double *diag_data, *offd_data;
1252 diag_i = A->diag->i;
1253 diag_j = A->diag->j;
1254 diag_data = A->diag->data;
1255 offd_i = A->offd->i;
1256 offd_j = A->offd->j;
1257 offd_data = A->offd->data;
1258 offd_col_map = A->col_map_offd;
1260 diag_nnz = offd_nnz = 0;
1261 for (HYPRE_Int i = 0, j = 0; i < nrows; i++)
1263 diag_i[i] = diag_nnz;
1264 offd_i[i] = offd_nnz;
1265 for (HYPRE_Int j_end = I[i+1]; j < j_end; j++)
1268 if (my_col_start <= glob_col && glob_col < my_col_end)
1270 diag_j[diag_nnz] = glob_col - my_col_start;
1271 diag_data[diag_nnz] = data[j];
1276 offd_j[offd_nnz] = offd_map[glob_col];
1277 offd_data[offd_nnz] = data[j];
1282 diag_i[nrows] = diag_nnz;
1283 offd_i[nrows] = offd_nnz;
1284 for (
auto it = offd_map.begin(); it != offd_map.end(); ++it)
1286 offd_col_map[it->second] = it->first;
1289 hypre_ParCSRMatrixSetNumNonzeros(A);
1291 if (row_starts == col_starts)
1293 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1295 #if MFEM_HYPRE_VERSION > 22200 1296 mfem_hypre_TFree_host(row_starts);
1299 mfem_hypre_TFree_host(col_starts);
1302 hypre_MatvecCommPkgCreate(A);
1312 hypre_ParCSRMatrix *Ph =
static_cast<hypre_ParCSRMatrix *
>(P);
1317 A = hypre_ParCSRMatrixCompleteClone(Ph);
1319 hypre_ParCSRMatrixCopy(Ph, A, 1);
1327 hypre_ParCSRMatrixSetNumNonzeros(A);
1329 hypre_MatvecCommPkgCreate(A);
1358 MFEM_ASSERT(diagOwner < 0 && offdOwner < 0 && colMapOwner == -1,
"");
1359 MFEM_ASSERT(diagOwner == offdOwner,
"");
1360 MFEM_ASSERT(ParCSROwner,
"");
1361 hypre_ParCSRMatrix *R = A;
1362 #ifdef HYPRE_USING_GPU 1366 ParCSROwner =
false;
1394 colMapOwner = colmap;
1399 #if MFEM_HYPRE_VERSION <= 22200 1400 if (!A || hypre_ParCSRMatrixOwnsRowStarts(A) ||
1401 (hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
1402 hypre_ParCSRMatrixOwnsColStarts(A)))
1407 int row_starts_size;
1408 if (HYPRE_AssumedPartitionCheck())
1410 row_starts_size = 2;
1414 MPI_Comm_size(hypre_ParCSRMatrixComm(A), &row_starts_size);
1418 HYPRE_BigInt *old_row_starts = hypre_ParCSRMatrixRowStarts(A);
1421 for (
int i = 0; i < row_starts_size; i++)
1423 new_row_starts[i] = old_row_starts[i];
1426 hypre_ParCSRMatrixRowStarts(A) = new_row_starts;
1427 hypre_ParCSRMatrixOwnsRowStarts(A) = 1;
1429 if (hypre_ParCSRMatrixColStarts(A) == old_row_starts)
1431 hypre_ParCSRMatrixColStarts(A) = new_row_starts;
1432 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
1439 #if MFEM_HYPRE_VERSION <= 22200 1440 if (!A || hypre_ParCSRMatrixOwnsColStarts(A) ||
1441 (hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
1442 hypre_ParCSRMatrixOwnsRowStarts(A)))
1447 int col_starts_size;
1448 if (HYPRE_AssumedPartitionCheck())
1450 col_starts_size = 2;
1454 MPI_Comm_size(hypre_ParCSRMatrixComm(A), &col_starts_size);
1458 HYPRE_BigInt *old_col_starts = hypre_ParCSRMatrixColStarts(A);
1461 for (
int i = 0; i < col_starts_size; i++)
1463 new_col_starts[i] = old_col_starts[i];
1466 hypre_ParCSRMatrixColStarts(A) = new_col_starts;
1468 if (hypre_ParCSRMatrixRowStarts(A) == old_col_starts)
1470 hypre_ParCSRMatrixRowStarts(A) = new_col_starts;
1471 hypre_ParCSRMatrixOwnsRowStarts(A) = 1;
1472 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
1476 hypre_ParCSRMatrixOwnsColStarts(A) = 1;
1483 const int size =
Height();
1485 #ifdef HYPRE_USING_GPU 1488 MFEM_ASSERT(A->diag->memory_location == HYPRE_MEMORY_DEVICE,
"");
1489 double *d_diag = diag.
Write();
1490 const HYPRE_Int *A_diag_i = A->diag->i;
1491 const double *A_diag_d = A->diag->data;
1492 MFEM_FORALL(i, size, d_diag[i] = A_diag_d[A_diag_i[i]];);
1499 for (
int j = 0; j < size; j++)
1501 diag(j) = A->diag->data[A->diag->i[j]];
1502 MFEM_ASSERT(A->diag->j[A->diag->i[j]] == j,
1503 "the first entry in each row must be the diagonal one");
1509 static void MakeSparseMatrixWrapper(
int nrows,
int ncols,
1510 HYPRE_Int *I, HYPRE_Int *J,
double *data,
1513 #ifndef HYPRE_BIGINT 1514 SparseMatrix tmp(I, J, data, nrows, ncols,
false,
false,
false);
1517 for (
int i = 0; i <= nrows; i++)
1521 const int nnz = mI[nrows];
1522 int *mJ = Memory<int>(nnz);
1523 for (
int j = 0; j < nnz; j++)
1527 SparseMatrix tmp(mI, mJ, data, nrows, ncols,
true,
false,
false);
1532 static void MakeWrapper(
const hypre_CSRMatrix *mat,
1533 const MemoryIJData &mem,
1534 SparseMatrix &wrapper)
1542 MakeSparseMatrixWrapper(nrows, ncols,
1543 const_cast<HYPRE_Int*>(I),
1544 const_cast<HYPRE_Int*>(J),
1545 const_cast<double*>(data),
1551 MakeWrapper(A->diag, mem_diag, diag);
1556 MakeWrapper(A->offd, mem_offd, offd);
1557 cmap = A->col_map_offd;
1563 hypre_CSRMatrix *hypre_merged = hypre_MergeDiagAndOffd(A);
1567 #if MFEM_HYPRE_VERSION >= 21600 1568 hypre_CSRMatrixBigJtoJ(hypre_merged);
1570 MakeSparseMatrixWrapper(
1579 merged = merged_tmp;
1581 hypre_CSRMatrixDestroy(hypre_merged);
1585 bool interleaved_rows,
1586 bool interleaved_cols)
const 1591 hypre_ParCSRMatrix **hypre_blocks =
new hypre_ParCSRMatrix*[nr * nc];
1593 internal::hypre_ParCSRMatrixSplit(A, nr, nc, hypre_blocks,
1594 interleaved_rows, interleaved_cols);
1597 for (
int i = 0; i < nr; i++)
1599 for (
int j = 0; j < nc; j++)
1605 delete [] hypre_blocks;
1610 hypre_ParCSRMatrix * At;
1611 hypre_ParCSRMatrixTranspose(A, &At, 1);
1612 hypre_ParCSRMatrixSetNumNonzeros(At);
1614 if (!hypre_ParCSRMatrixCommPkg(At)) { hypre_MatvecCommPkgCreate(At); }
1620 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(At));
1626 #if MFEM_HYPRE_VERSION >= 21800 1628 double threshold)
const 1636 hypre_MatvecCommPkgCreate(A);
1639 hypre_ParCSRMatrix *submat;
1642 int local_num_vars = hypre_CSRMatrixNumRows(hypre_ParCSRMatrixDiag(A));
1645 #ifdef hypre_IntArrayData 1647 hypre_IntArray *CF_marker;
1649 CF_marker = hypre_IntArrayCreate(local_num_vars);
1650 hypre_IntArrayInitialize_v2(CF_marker, HYPRE_MEMORY_HOST);
1651 hypre_IntArraySetConstantValues(CF_marker, 1);
1656 for (
int j=0; j<indices.
Size(); j++)
1658 if (indices[j] > local_num_vars)
1660 MFEM_WARNING(
"WARNING : " << indices[j] <<
" > " << local_num_vars);
1662 #ifdef hypre_IntArrayData 1663 hypre_IntArrayData(CF_marker)[indices[j]] = -1;
1665 CF_marker[indices[j]] = -1;
1670 #if (MFEM_HYPRE_VERSION > 22300) || (MFEM_HYPRE_VERSION == 22300 && HYPRE_DEVELOP_NUMBER >=8) 1673 hypre_BoomerAMGCoarseParms(MPI_COMM_WORLD, local_num_vars, 1, NULL,
1674 CF_marker, NULL, cpts_global);
1677 hypre_BoomerAMGCoarseParms(MPI_COMM_WORLD, local_num_vars, 1, NULL,
1678 CF_marker, NULL, &cpts_global);
1682 #ifdef hypre_IntArrayData 1683 hypre_ParCSRMatrixExtractSubmatrixFC(A, hypre_IntArrayData(CF_marker),
1684 cpts_global,
"FF", &submat,
1687 hypre_ParCSRMatrixExtractSubmatrixFC(A, CF_marker, cpts_global,
1688 "FF", &submat, threshold);
1691 #if (MFEM_HYPRE_VERSION <= 22300) && !(MFEM_HYPRE_VERSION == 22300 && HYPRE_DEVELOP_NUMBER >=8) 1692 mfem_hypre_TFree(cpts_global);
1694 #ifdef hypre_IntArrayData 1695 hypre_IntArrayDestroy(CF_marker);
1706 #if (MFEM_HYPRE_VERSION == 22500 && HYPRE_DEVELOP_NUMBER >= 1) || \ 1707 (MFEM_HYPRE_VERSION > 22500) 1708 #ifdef HYPRE_USING_GPU 1709 hypre_ParCSRMatrixLocalTranspose(A);
1716 #if (MFEM_HYPRE_VERSION == 22500 && HYPRE_DEVELOP_NUMBER >= 1) || \ 1717 (MFEM_HYPRE_VERSION > 22500) 1718 #ifdef HYPRE_USING_GPU 1721 hypre_CSRMatrixDestroy(A->diagT);
1726 hypre_CSRMatrixDestroy(A->offdT);
1734 double a,
double b)
const 1738 return hypre_ParCSRMatrixMatvec(
a, A, x,
b, y);
1743 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1744 <<
", expected size = " <<
Width());
1745 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1746 <<
", expected size = " <<
Height());
1793 hypre_ParCSRMatrixMatvec(
a, A, *X,
b, *Y);
1795 if (!yshallow) { y = *Y; }
1801 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
1802 <<
", expected size = " <<
Height());
1803 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
1804 <<
", expected size = " <<
Width());
1857 hypre_ParCSRMatrixMatvecT(
a, A, *Y,
b, *X);
1859 if (!yshallow) { y = *X; }
1863 double a,
double b)
const 1865 return hypre_ParCSRMatrixMatvec(
a, A, (hypre_ParVector *) x,
b,
1866 (hypre_ParVector *) y);
1870 double a,
double b)
const 1875 return hypre_ParCSRMatrixMatvecT(
a, A, x,
b, y);
1881 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1882 <<
", expected size = " <<
Width());
1883 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1884 <<
", expected size = " <<
Height());
1890 internal::hypre_ParCSRMatrixAbsMatvec(A,
a, const_cast<double*>(x_data),
1898 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
1899 <<
", expected size = " <<
Height());
1900 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
1901 <<
", expected size = " <<
Width());
1907 internal::hypre_ParCSRMatrixAbsMatvecT(A,
a, const_cast<double*>(x_data),
1915 const bool assumed_partition = HYPRE_AssumedPartitionCheck();
1916 const bool row_starts_given = (row_starts != NULL);
1917 if (!row_starts_given)
1919 row_starts = hypre_ParCSRMatrixRowStarts(A);
1920 MFEM_VERIFY(D.
Height() == hypre_CSRMatrixNumRows(A->diag),
1921 "the matrix D is NOT compatible with the row starts of" 1922 " this HypreParMatrix, row_starts must be given.");
1927 if (assumed_partition)
1933 MPI_Comm_rank(
GetComm(), &offset);
1935 int local_num_rows = row_starts[offset+1]-row_starts[offset];
1936 MFEM_VERIFY(local_num_rows == D.
Height(),
"the number of rows in D is " 1937 " not compatible with the given row_starts");
1944 if (assumed_partition)
1947 if (row_starts_given)
1949 global_num_rows = row_starts[2];
1956 global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
1961 MPI_Comm_size(
GetComm(), &part_size);
1962 global_num_rows = row_starts[part_size];
1966 HYPRE_BigInt *col_starts = hypre_ParCSRMatrixColStarts(A);
1972 GetOffd(A_offd, col_map_offd);
1982 DuplicateAs<HYPRE_BigInt>(row_starts, part_size,
false);
1984 (row_starts == col_starts ? new_row_starts :
1985 DuplicateAs<HYPRE_BigInt>(col_starts, part_size,
false));
1987 DuplicateAs<HYPRE_BigInt>(col_map_offd, A_offd.
Width());
1991 const bool own_diag_offd =
true;
1996 global_num_rows, hypre_ParCSRMatrixGlobalNumCols(A),
1997 new_row_starts, new_col_starts,
1998 DA_diag, DA_offd, new_col_map_offd,
2001 #if MFEM_HYPRE_VERSION <= 22200 2003 hypre_ParCSRMatrixSetRowStartsOwner(DA->A, 1);
2004 hypre_ParCSRMatrixSetColStartsOwner(DA->A, 1);
2006 mfem_hypre_TFree_host(new_row_starts);
2007 mfem_hypre_TFree_host(new_col_starts);
2009 DA->colMapOwner = 1;
2016 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
2021 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
2023 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
2030 double *Adiag_data = hypre_CSRMatrixData(A->diag);
2031 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
2033 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
2034 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
2037 for (
int i(0); i < size; ++i)
2040 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
2042 Adiag_data[jj] *= val;
2044 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
2046 Aoffd_data[jj] *= val;
2055 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
2060 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
2062 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
2069 double *Adiag_data = hypre_CSRMatrixData(A->diag);
2070 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
2073 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
2074 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
2077 for (
int i(0); i < size; ++i)
2082 mfem_error(
"HypreParMatrix::InvDiagScale : Division by 0");
2086 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
2088 Adiag_data[jj] *= val;
2090 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
2092 Aoffd_data[jj] *= val;
2101 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
2108 HYPRE_Int size=hypre_CSRMatrixNumRows(A->diag);
2111 double *Adiag_data = hypre_CSRMatrixData(A->diag);
2112 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
2113 for (jj = 0; jj < Adiag_i[size]; ++jj)
2115 Adiag_data[jj] *=
s;
2118 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
2119 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
2120 for (jj = 0; jj < Aoffd_i[size]; ++jj)
2122 Aoffd_data[jj] *=
s;
2128 static void get_sorted_rows_cols(
const Array<int> &rows_cols,
2134 for (
int i = 0; i < rows_cols.
Size(); i++)
2136 hypre_sorted[i] = rows_cols[i];
2137 if (i && rows_cols[i-1] > rows_cols[i]) { sorted =
false; }
2139 if (!sorted) { hypre_sorted.
Sort(); }
2147 hypre_CSRMatrix * csr_A;
2148 hypre_CSRMatrix * csr_A_wo_z;
2149 hypre_ParCSRMatrix * parcsr_A_ptr;
2154 comm = hypre_ParCSRMatrixComm(A);
2156 ierr += hypre_ParCSRMatrixGetLocalRange(A,
2157 &row_start,&row_end,
2158 &col_start,&col_end );
2160 row_starts = hypre_ParCSRMatrixRowStarts(A);
2161 col_starts = hypre_ParCSRMatrixColStarts(A);
2163 #if MFEM_HYPRE_VERSION <= 22200 2164 bool old_owns_row = hypre_ParCSRMatrixOwnsRowStarts(A);
2165 bool old_owns_col = hypre_ParCSRMatrixOwnsColStarts(A);
2167 HYPRE_BigInt global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
2168 HYPRE_BigInt global_num_cols = hypre_ParCSRMatrixGlobalNumCols(A);
2169 parcsr_A_ptr = hypre_ParCSRMatrixCreate(comm, global_num_rows,
2171 row_starts, col_starts,
2173 #if MFEM_HYPRE_VERSION <= 22200 2174 hypre_ParCSRMatrixOwnsRowStarts(parcsr_A_ptr) = old_owns_row;
2175 hypre_ParCSRMatrixOwnsColStarts(parcsr_A_ptr) = old_owns_col;
2176 hypre_ParCSRMatrixOwnsRowStarts(A) = 0;
2177 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
2180 csr_A = hypre_MergeDiagAndOffd(A);
2186 csr_A_wo_z = hypre_CSRMatrixDeleteZeros(csr_A,threshold);
2190 if (csr_A_wo_z == NULL)
2196 ierr += hypre_CSRMatrixDestroy(csr_A);
2202 ierr += GenerateDiagAndOffd(csr_A_wo_z,parcsr_A_ptr,
2205 ierr += hypre_CSRMatrixDestroy(csr_A_wo_z);
2207 MFEM_VERIFY(ierr == 0,
"");
2211 hypre_ParCSRMatrixSetNumNonzeros(A);
2213 #if MFEM_HYPRE_VERSION <= 22200 2214 if (row_starts == col_starts)
2216 if ((row_starts[0] == col_starts[0]) &&
2217 (row_starts[1] == col_starts[1]))
2220 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
2222 if (!hypre_ParCSRMatrixCommPkg(A)) { hypre_MatvecCommPkgCreate(A); }
2229 HYPRE_Int old_err = hypre_error_flag;
2230 hypre_error_flag = 0;
2232 #if MFEM_HYPRE_VERSION < 21400 2234 double threshold = 0.0;
2237 HYPRE_Int *diag_I = A->diag->i, *offd_I = A->offd->i;
2238 double *diag_d = A->diag->data, *offd_d = A->offd->data;
2239 HYPRE_Int local_num_rows = A->diag->num_rows;
2240 double max_l2_row_norm = 0.0;
2242 for (HYPRE_Int r = 0; r < local_num_rows; r++)
2245 double l2_row_norm = row.
Norml2();
2247 l2_row_norm = std::hypot(l2_row_norm, row.
Norml2());
2248 max_l2_row_norm = std::max(max_l2_row_norm, l2_row_norm);
2250 double loc_max_l2_row_norm = max_l2_row_norm;
2251 MPI_Allreduce(&loc_max_l2_row_norm, &max_l2_row_norm, 1, MPI_DOUBLE,
2253 threshold = tol * max_l2_row_norm;
2258 #elif MFEM_HYPRE_VERSION < 21800 2260 HYPRE_Int err_flag = hypre_ParCSRMatrixDropSmallEntries(A, tol);
2261 MFEM_VERIFY(!err_flag,
"error encountered: error code = " << err_flag);
2265 HYPRE_Int err_flag = hypre_ParCSRMatrixDropSmallEntries(A, tol, 2);
2266 MFEM_VERIFY(!err_flag,
"error encountered: error code = " << err_flag);
2270 hypre_error_flag = old_err;
2278 get_sorted_rows_cols(rows_cols, rc_sorted);
2280 internal::hypre_ParCSRMatrixEliminateAXB(
2287 get_sorted_rows_cols(rows_cols, rc_sorted);
2289 hypre_ParCSRMatrix* Ae;
2291 internal::hypre_ParCSRMatrixEliminateAAe(
2301 get_sorted_rows_cols(cols, rc_sorted);
2303 hypre_ParCSRMatrix* Ae;
2305 internal::hypre_ParCSRMatrixEliminateAAe(
2306 A, &Ae, rc_sorted.
Size(), rc_sorted.
GetData(), 1);
2314 if (rows.
Size() > 0)
2317 get_sorted_rows_cols(rows, r_sorted);
2319 internal::hypre_ParCSRMatrixEliminateRows(A, r_sorted.
Size(),
2330 Ae.
Mult(-1.0, x, 1.0,
b);
2334 if (ess_dof_list.
Size() == 0) {
return; }
2337 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
2338 double *data = hypre_CSRMatrixData(A_diag);
2339 HYPRE_Int *I = hypre_CSRMatrixI(A_diag);
2341 HYPRE_Int *J = hypre_CSRMatrixJ(A_diag);
2342 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
2343 HYPRE_Int *I_offd = hypre_CSRMatrixI(A_offd);
2344 double *data_offd = hypre_CSRMatrixData(A_offd);
2351 for (
int i = 0; i < ess_dof_list.
Size(); i++)
2353 int r = ess_dof_list[i];
2354 b(r) = data[I[r]] * x(r);
2356 MFEM_ASSERT(I[r] < I[r+1],
"empty row found!");
2362 MFEM_ABORT(
"the diagonal entry must be the first entry in the row!");
2364 for (
int j = I[r]+1; j < I[r+1]; j++)
2368 MFEM_ABORT(
"all off-diagonal entries must be zero!");
2371 for (
int j = I_offd[r]; j < I_offd[r+1]; j++)
2373 if (data_offd[j] != 0.0)
2375 MFEM_ABORT(
"all off-diagonal entries must be zero!");
2386 hypre_ParCSRMatrix *A_hypre = *
this;
2389 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A_hypre);
2390 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A_hypre);
2392 HYPRE_Int diag_nrows = hypre_CSRMatrixNumRows(diag);
2393 HYPRE_Int offd_ncols = hypre_CSRMatrixNumCols(offd);
2395 const int n_ess_dofs = ess_dofs.
Size();
2401 hypre_ParCSRCommHandle *comm_handle;
2402 HYPRE_Int *int_buf_data, *eliminate_row, *eliminate_col;
2404 eliminate_row = mfem_hypre_CTAlloc(HYPRE_Int, diag_nrows);
2405 eliminate_col = mfem_hypre_CTAlloc(HYPRE_Int, offd_ncols);
2408 hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg(A_hypre);
2411 hypre_MatvecCommPkgCreate(A_hypre);
2412 comm_pkg = hypre_ParCSRMatrixCommPkg(A_hypre);
2416 MFEM_HYPRE_FORALL(i, diag_nrows, eliminate_row[i] = 0; );
2417 MFEM_HYPRE_FORALL(i, n_ess_dofs, eliminate_row[ess_dofs_d[i]] = 1; );
2422 HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
2423 HYPRE_Int int_buf_sz = hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends);
2424 int_buf_data = mfem_hypre_CTAlloc(HYPRE_Int, int_buf_sz);
2426 HYPRE_Int *send_map_elmts;
2427 #if defined(HYPRE_USING_GPU) 2428 hypre_ParCSRCommPkgCopySendMapElmtsToDevice(comm_pkg);
2429 send_map_elmts = hypre_ParCSRCommPkgDeviceSendMapElmts(comm_pkg);
2431 send_map_elmts = hypre_ParCSRCommPkgSendMapElmts(comm_pkg);
2433 MFEM_HYPRE_FORALL(i, int_buf_sz,
2435 int k = send_map_elmts[i];
2436 int_buf_data[i] = eliminate_row[k];
2439 #if defined(HYPRE_USING_GPU) 2441 comm_handle = hypre_ParCSRCommHandleCreate_v2(
2442 11, comm_pkg, HYPRE_MEMORY_DEVICE, int_buf_data,
2443 HYPRE_MEMORY_DEVICE, eliminate_col);
2445 comm_handle = hypre_ParCSRCommHandleCreate(
2446 11, comm_pkg, int_buf_data, eliminate_col );
2452 const auto I = diag->i;
2453 const auto J = diag->j;
2454 auto data = diag->data;
2456 MFEM_HYPRE_FORALL(i, n_ess_dofs,
2458 const int idof = ess_dofs_d[i];
2459 for (
int j=I[idof]; j<I[idof+1]; ++j)
2461 const int jdof = J[j];
2464 if (diag_policy == DiagonalPolicy::DIAG_ONE)
2468 else if (diag_policy == DiagonalPolicy::DIAG_ZERO)
2477 for (
int k=I[jdof]; k<I[jdof+1]; ++k)
2492 const auto I = offd->i;
2493 auto data = offd->data;
2494 MFEM_HYPRE_FORALL(i, n_ess_dofs,
2496 const int idof = ess_dofs_d[i];
2497 for (
int j=I[idof]; j<I[idof+1]; ++j)
2505 hypre_ParCSRCommHandleDestroy(comm_handle);
2506 mfem_hypre_TFree(int_buf_data);
2507 mfem_hypre_TFree(eliminate_row);
2511 const int nrows_offd = hypre_CSRMatrixNumRows(offd);
2512 const auto I = offd->i;
2513 const auto J = offd->j;
2514 auto data = offd->data;
2515 MFEM_HYPRE_FORALL(i, nrows_offd,
2517 for (
int j=I[i]; j<I[i+1]; ++j)
2519 data[j] *= 1 - eliminate_col[J[j]];
2524 mfem_hypre_TFree(eliminate_col);
2528 HYPRE_Int offj)
const 2531 hypre_ParCSRMatrixPrintIJ(A,offi,offj,fname);
2535 void HypreParMatrix::Read(MPI_Comm comm,
const char *fname)
2540 HYPRE_Int base_i, base_j;
2541 hypre_ParCSRMatrixReadIJ(comm, fname, &base_i, &base_j, &A);
2542 hypre_ParCSRMatrixSetNumNonzeros(A);
2544 if (!hypre_ParCSRMatrixCommPkg(A)) { hypre_MatvecCommPkgCreate(A); }
2555 HYPRE_IJMatrix A_ij;
2556 HYPRE_IJMatrixRead(fname, comm, 5555, &A_ij);
2558 HYPRE_ParCSRMatrix A_parcsr;
2559 HYPRE_IJMatrixGetObject(A_ij, (
void**) &A_parcsr);
2561 A = (hypre_ParCSRMatrix*)A_parcsr;
2563 hypre_ParCSRMatrixSetNumNonzeros(A);
2565 if (!hypre_ParCSRMatrixCommPkg(A)) { hypre_MatvecCommPkgCreate(A); }
2573 hypre_ParCSRCommPkg *comm_pkg = A->comm_pkg;
2574 MPI_Comm comm = A->comm;
2576 const int tag = 46801;
2578 MPI_Comm_rank(comm, &myid);
2579 MPI_Comm_size(comm, &nproc);
2583 MPI_Recv(&c, 1, MPI_CHAR, myid-1, tag, comm, MPI_STATUS_IGNORE);
2587 os <<
"\nHypreParMatrix: hypre_ParCSRCommPkg:\n";
2589 os <<
"Rank " << myid <<
":\n" 2590 " number of sends = " << comm_pkg->num_sends <<
2591 " (" <<
sizeof(double)*comm_pkg->send_map_starts[comm_pkg->num_sends] <<
2593 " number of recvs = " << comm_pkg->num_recvs <<
2594 " (" <<
sizeof(
double)*comm_pkg->recv_vec_starts[comm_pkg->num_recvs] <<
2596 if (myid != nproc-1)
2599 MPI_Send(&c, 1, MPI_CHAR, myid+1, tag, comm);
2612 os <<
"global number of rows : " << A->global_num_rows <<
'\n' 2613 <<
"global number of columns : " << A->global_num_cols <<
'\n' 2614 <<
"first row index : " << A->first_row_index <<
'\n' 2615 <<
" last row index : " << A->last_row_index <<
'\n' 2616 <<
"first col diag : " << A->first_col_diag <<
'\n' 2617 <<
" last col diag : " << A->last_col_diag <<
'\n' 2618 <<
"number of nonzeros : " << A->num_nonzeros <<
'\n';
2620 hypre_CSRMatrix *csr = A->diag;
2621 const char *csr_name =
"diag";
2622 for (
int m = 0; m < 2; m++)
2624 auto csr_nnz = csr->i[csr->num_rows];
2625 os << csr_name <<
" num rows : " << csr->num_rows <<
'\n' 2626 << csr_name <<
" num cols : " << csr->num_cols <<
'\n' 2627 << csr_name <<
" num nnz : " << csr->num_nonzeros <<
'\n' 2628 << csr_name <<
" i last : " << csr_nnz
2629 << (csr_nnz == csr->num_nonzeros ?
2630 " [good]" :
" [** BAD **]") <<
'\n';
2632 os << csr_name <<
" i hash : " << hf.
GetHash() <<
'\n';
2633 os << csr_name <<
" j hash : ";
2634 if (csr->j ==
nullptr)
2643 #if MFEM_HYPRE_VERSION >= 21600 2644 os << csr_name <<
" big j hash : ";
2645 if (csr->big_j ==
nullptr)
2655 os << csr_name <<
" data hash : ";
2656 if (csr->data ==
nullptr)
2670 hf.
AppendInts(A->col_map_offd, A->offd->num_cols);
2671 os <<
"col map offd hash : " << hf.
GetHash() <<
'\n';
2676 HYPRE_BigInt *A_col_map_offd = hypre_ParCSRMatrixColMapOffd(A);
2677 int size = hypre_CSRMatrixNumCols(hypre_ParCSRMatrixOffd(A));
2681 void HypreParMatrix::Destroy()
2683 if ( X != NULL ) {
delete X; }
2684 if ( Y != NULL ) {
delete Y; }
2688 if (A == NULL) {
return; }
2690 #ifdef HYPRE_USING_GPU 2691 if (ParCSROwner && (diagOwner < 0 || offdOwner < 0))
2699 MFEM_VERIFY(!(diagOwner < 0 && offdOwner < 0) || diagOwner == offdOwner,
2702 MemoryClass mc = (diagOwner == -1 || offdOwner == -1) ?
2704 Write(mc, diagOwner < 0, offdOwner <0);
2713 hypre_CSRMatrixI(A->diag) = NULL;
2714 hypre_CSRMatrixJ(A->diag) = NULL;
2715 hypre_CSRMatrixData(A->diag) = NULL;
2722 hypre_CSRMatrixI(A->offd) = NULL;
2723 hypre_CSRMatrixJ(A->offd) = NULL;
2724 hypre_CSRMatrixData(A->offd) = NULL;
2726 if (colMapOwner >= 0)
2728 if (colMapOwner & 1)
2732 hypre_ParCSRMatrixColMapOffd(A) = NULL;
2737 hypre_ParCSRMatrixDestroy(A);
2743 #ifndef HYPRE_BIGINT 2746 MFEM_CONTRACT_VAR(own_j);
2747 MFEM_ASSERT(own_i == own_j,
"Inconsistent ownership");
2761 #if MFEM_HYPRE_VERSION >= 21800 2770 hypre_ParCSRMatrix *C_hypre;
2771 hypre_ParcsrBdiagInvScal(*A, blocksize, &C_hypre);
2772 hypre_ParCSRMatrixDropSmallEntries(C_hypre, 1e-15, 1);
2782 hypre_ParVector *d_hypre;
2783 hypre_ParvecBdiagInvScal(b_Hypre, blocksize, &d_hypre, *A);
2791 #if MFEM_HYPRE_VERSION < 21400 2796 hypre_ParCSRMatrix *C_hypre =
2797 internal::hypre_ParCSRMatrixAdd(const_cast<HypreParMatrix &>(A),
2798 const_cast<HypreParMatrix &>(B));
2799 MFEM_VERIFY(C_hypre,
"error in hypre_ParCSRMatrixAdd");
2801 if (!hypre_ParCSRMatrixCommPkg(C_hypre)) { hypre_MatvecCommPkgCreate(C_hypre); }
2812 hypre_ParCSRMatrix * C = internal::hypre_ParCSRMatrixAdd(*A,*B);
2814 if (!hypre_ParCSRMatrixCommPkg(C)) { hypre_MatvecCommPkgCreate(C); }
2821 HypreParMatrix *
Add(
double alpha,
const HypreParMatrix &A,
2822 double beta,
const HypreParMatrix &B)
2824 hypre_ParCSRMatrix *C;
2825 #if MFEM_HYPRE_VERSION <= 22000 2826 hypre_ParcsrAdd(
alpha, A, beta, B, &C);
2828 hypre_ParCSRMatrixAdd(
alpha, A, beta, B, &C);
2830 if (!hypre_ParCSRMatrixCommPkg(C)) { hypre_MatvecCommPkgCreate(C); }
2832 return new HypreParMatrix(C);
2835 HypreParMatrix *
ParAdd(
const HypreParMatrix *A,
const HypreParMatrix *B)
2837 hypre_ParCSRMatrix *C;
2838 #if MFEM_HYPRE_VERSION <= 22000 2839 hypre_ParcsrAdd(1.0, *A, 1.0, *B, &C);
2841 hypre_ParCSRMatrixAdd(1.0, *A, 1.0, *B, &C);
2843 if (!hypre_ParCSRMatrixCommPkg(C)) { hypre_MatvecCommPkgCreate(C); }
2845 return new HypreParMatrix(C);
2853 hypre_ParCSRMatrix * ab;
2854 #ifdef HYPRE_USING_GPU 2855 ab = hypre_ParCSRMatMat(*A, *B);
2857 ab = hypre_ParMatmul(*A,*B);
2859 hypre_ParCSRMatrixSetNumNonzeros(ab);
2861 if (!hypre_ParCSRMatrixCommPkg(ab)) { hypre_MatvecCommPkgCreate(ab); }
2873 hypre_ParCSRMatrix * rap;
2875 #ifdef HYPRE_USING_GPU 2883 hypre_ParCSRMatrix *Q = hypre_ParCSRMatMat(*A,*P);
2884 const bool keepTranspose =
false;
2885 rap = hypre_ParCSRTMatMatKT(*P,Q,keepTranspose);
2886 hypre_ParCSRMatrixDestroy(Q);
2892 #if MFEM_HYPRE_VERSION <= 22200 2893 HYPRE_Int P_owns_its_col_starts =
2894 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
2897 hypre_BoomerAMGBuildCoarseOperator(*P,*A,*P,&rap);
2899 #if MFEM_HYPRE_VERSION <= 22200 2902 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
2903 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
2904 if (P_owns_its_col_starts)
2906 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
2911 hypre_ParCSRMatrixSetNumNonzeros(rap);
2920 hypre_ParCSRMatrix * rap;
2922 #ifdef HYPRE_USING_GPU 2924 hypre_ParCSRMatrix *Q = hypre_ParCSRMatMat(*A,*P);
2925 rap = hypre_ParCSRTMatMat(*Rt,Q);
2926 hypre_ParCSRMatrixDestroy(Q);
2929 #if MFEM_HYPRE_VERSION <= 22200 2930 HYPRE_Int P_owns_its_col_starts =
2931 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
2932 HYPRE_Int Rt_owns_its_col_starts =
2933 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*Rt));
2936 hypre_BoomerAMGBuildCoarseOperator(*Rt,*A,*P,&rap);
2938 #if MFEM_HYPRE_VERSION <= 22200 2941 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
2942 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
2943 if (P_owns_its_col_starts)
2945 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
2947 if (Rt_owns_its_col_starts)
2949 hypre_ParCSRMatrixSetColStartsOwner(*Rt, 1);
2954 hypre_ParCSRMatrixSetNumNonzeros(rap);
2963 const int num_loc,
const Array<int> &offsets,
2964 std::vector<int> &all_num_loc,
const int numBlocks,
2965 std::vector<std::vector<HYPRE_BigInt>> &blockProcOffsets,
2966 std::vector<HYPRE_BigInt> &procOffsets,
2967 std::vector<std::vector<int>> &procBlockOffsets,
2970 std::vector<std::vector<int>> all_block_num_loc(numBlocks);
2972 MPI_Allgather(&num_loc, 1, MPI_INT, all_num_loc.data(), 1, MPI_INT, comm);
2974 for (
int j = 0; j < numBlocks; ++j)
2976 all_block_num_loc[j].resize(nprocs);
2977 blockProcOffsets[j].resize(nprocs);
2979 const int blockNumRows = offsets[j + 1] - offsets[j];
2980 MPI_Allgather(&blockNumRows, 1, MPI_INT, all_block_num_loc[j].data(), 1,
2982 blockProcOffsets[j][0] = 0;
2983 for (
int i = 0; i < nprocs - 1; ++i)
2985 blockProcOffsets[j][i + 1] = blockProcOffsets[j][i]
2986 + all_block_num_loc[j][i];
2993 for (
int i = 0; i < nprocs; ++i)
2995 globalNum += all_num_loc[i];
2998 MFEM_VERIFY(globalNum >= 0,
"overflow in global size");
3002 firstLocal += all_num_loc[i];
3007 procOffsets[i + 1] = procOffsets[i] + all_num_loc[i];
3010 procBlockOffsets[i].resize(numBlocks);
3011 procBlockOffsets[i][0] = 0;
3012 for (
int j = 1; j < numBlocks; ++j)
3014 procBlockOffsets[i][j] = procBlockOffsets[i][j - 1]
3015 + all_block_num_loc[j - 1][i];
3023 const int numBlockRows = blocks.
NumRows();
3024 const int numBlockCols = blocks.
NumCols();
3026 MFEM_VERIFY(numBlockRows > 0 &&
3027 numBlockCols > 0,
"Invalid input to HypreParMatrixFromBlocks");
3029 if (blockCoeff != NULL)
3031 MFEM_VERIFY(numBlockRows == blockCoeff->
NumRows() &&
3032 numBlockCols == blockCoeff->
NumCols(),
3033 "Invalid input to HypreParMatrixFromBlocks");
3039 int nonNullBlockRow0 = -1;
3040 for (
int j=0; j<numBlockCols; ++j)
3042 if (blocks(0,j) != NULL)
3044 nonNullBlockRow0 = j;
3049 MFEM_VERIFY(nonNullBlockRow0 >= 0,
"Null row of blocks");
3050 MPI_Comm comm = blocks(0,nonNullBlockRow0)->GetComm();
3055 for (
int i=0; i<numBlockRows; ++i)
3057 for (
int j=0; j<numBlockCols; ++j)
3059 if (blocks(i,j) != NULL)
3061 const int nrows = blocks(i,j)->
NumRows();
3062 const int ncols = blocks(i,j)->
NumCols();
3064 MFEM_VERIFY(nrows > 0 &&
3065 ncols > 0,
"Invalid block in HypreParMatrixFromBlocks");
3067 if (rowOffsets[i+1] == 0)
3069 rowOffsets[i+1] = nrows;
3073 MFEM_VERIFY(rowOffsets[i+1] == nrows,
3074 "Inconsistent blocks in HypreParMatrixFromBlocks");
3077 if (colOffsets[j+1] == 0)
3079 colOffsets[j+1] = ncols;
3083 MFEM_VERIFY(colOffsets[j+1] == ncols,
3084 "Inconsistent blocks in HypreParMatrixFromBlocks");
3089 MFEM_VERIFY(rowOffsets[i+1] > 0,
"Invalid input blocks");
3090 rowOffsets[i+1] += rowOffsets[i];
3093 for (
int j=0; j<numBlockCols; ++j)
3095 MFEM_VERIFY(colOffsets[j+1] > 0,
"Invalid input blocks");
3096 colOffsets[j+1] += colOffsets[j];
3099 const int num_loc_rows = rowOffsets[numBlockRows];
3100 const int num_loc_cols = colOffsets[numBlockCols];
3103 MPI_Comm_rank(comm, &rank);
3104 MPI_Comm_size(comm, &nprocs);
3106 std::vector<int> all_num_loc_rows(nprocs);
3107 std::vector<int> all_num_loc_cols(nprocs);
3108 std::vector<HYPRE_BigInt> procRowOffsets(nprocs);
3109 std::vector<HYPRE_BigInt> procColOffsets(nprocs);
3110 std::vector<std::vector<HYPRE_BigInt>> blockRowProcOffsets(numBlockRows);
3111 std::vector<std::vector<HYPRE_BigInt>> blockColProcOffsets(numBlockCols);
3112 std::vector<std::vector<int>> procBlockRowOffsets(nprocs);
3113 std::vector<std::vector<int>> procBlockColOffsets(nprocs);
3115 HYPRE_BigInt first_loc_row, glob_nrows, first_loc_col, glob_ncols;
3117 all_num_loc_rows, numBlockRows, blockRowProcOffsets,
3118 procRowOffsets, procBlockRowOffsets, first_loc_row,
3122 all_num_loc_cols, numBlockCols, blockColProcOffsets,
3123 procColOffsets, procBlockColOffsets, first_loc_col,
3126 std::vector<int> opI(num_loc_rows + 1);
3127 std::vector<int> cnt(num_loc_rows);
3129 for (
int i = 0; i < num_loc_rows; ++i)
3135 opI[num_loc_rows] = 0;
3140 for (
int i = 0; i < numBlockRows; ++i)
3142 for (
int j = 0; j < numBlockCols; ++j)
3144 if (blocks(i, j) == NULL)
3146 csr_blocks(i, j) = NULL;
3150 blocks(i, j)->HostRead();
3151 csr_blocks(i, j) = hypre_MergeDiagAndOffd(*blocks(i, j));
3152 blocks(i, j)->HypreRead();
3154 for (
int k = 0; k < csr_blocks(i, j)->num_rows; ++k)
3156 opI[rowOffsets[i] + k + 1] +=
3157 csr_blocks(i, j)->i[k + 1] - csr_blocks(i, j)->i[k];
3164 for (
int i = 0; i < num_loc_rows; ++i)
3166 opI[i + 1] += opI[i];
3169 const int nnz = opI[num_loc_rows];
3171 std::vector<HYPRE_BigInt> opJ(nnz);
3172 std::vector<double> data(nnz);
3175 for (
int i = 0; i < numBlockRows; ++i)
3177 for (
int j = 0; j < numBlockCols; ++j)
3179 if (csr_blocks(i, j) != NULL)
3181 const int nrows = csr_blocks(i, j)->num_rows;
3182 const double cij = blockCoeff ? (*blockCoeff)(i, j) : 1.0;
3183 #if MFEM_HYPRE_VERSION >= 21600 3184 const bool usingBigJ = (csr_blocks(i, j)->big_j != NULL);
3187 for (
int k = 0; k < nrows; ++k)
3189 const int rowg = rowOffsets[i] + k;
3190 const int nnz_k = csr_blocks(i,j)->i[k+1]-csr_blocks(i,j)->i[k];
3191 const int osk = csr_blocks(i, j)->i[k];
3193 for (
int l = 0; l < nnz_k; ++l)
3196 #if MFEM_HYPRE_VERSION >= 21600 3197 const HYPRE_Int bcol = usingBigJ ?
3198 csr_blocks(i, j)->big_j[osk + l] :
3199 csr_blocks(i, j)->j[osk + l];
3201 const HYPRE_Int bcol = csr_blocks(i, j)->j[osk + l];
3205 const auto &offs = blockColProcOffsets[j];
3206 const int bcolproc =
3207 std::upper_bound(offs.begin() + 1, offs.end(), bcol)
3210 opJ[opI[rowg] + cnt[rowg]] = procColOffsets[bcolproc] +
3211 procBlockColOffsets[bcolproc][j]
3213 - blockColProcOffsets[j][bcolproc];
3214 data[opI[rowg] + cnt[rowg]] = cij * csr_blocks(i, j)->data[osk + l];
3222 for (
int i = 0; i < numBlockRows; ++i)
3224 for (
int j = 0; j < numBlockCols; ++j)
3226 if (csr_blocks(i, j) != NULL)
3228 hypre_CSRMatrixDestroy(csr_blocks(i, j));
3233 MFEM_VERIFY(HYPRE_AssumedPartitionCheck(),
3234 "only 'assumed partition' mode is supported");
3236 std::vector<HYPRE_BigInt> rowStarts2(2);
3237 rowStarts2[0] = first_loc_row;
3238 rowStarts2[1] = first_loc_row + all_num_loc_rows[rank];
3240 int square = std::equal(all_num_loc_rows.begin(), all_num_loc_rows.end(),
3241 all_num_loc_cols.begin());
3244 return new HypreParMatrix(comm, num_loc_rows, glob_nrows, glob_ncols,
3245 opI.data(), opJ.data(),
3252 std::vector<HYPRE_BigInt> colStarts2(2);
3253 colStarts2[0] = first_loc_col;
3254 colStarts2[1] = first_loc_col + all_num_loc_cols[rank];
3256 return new HypreParMatrix(comm, num_loc_rows, glob_nrows, glob_ncols,
3257 opI.data(), opJ.data(),
3284 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
3285 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
3287 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(
u));
3288 double *r_data = hypre_VectorData(hypre_ParVectorLocalVector(r));
3290 for (
int i = 0; i < N; i++)
3293 hypre_ParVectorCopy(
f, r);
3294 hypre_ParCSRMatrixMatvec(-1.0, A,
u, 1.0, r);
3297 (0 == (i % 2)) ? coef = lambda : coef =
mu;
3299 for (HYPRE_Int j = 0; j < num_rows; j++)
3301 u_data[j] += coef*r_data[j] / max_eig;
3317 hypre_ParVector *x0,
3318 hypre_ParVector *x1,
3319 hypre_ParVector *x2,
3320 hypre_ParVector *x3)
3323 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
3324 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
3326 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(
u));
3328 double *x0_data = hypre_VectorData(hypre_ParVectorLocalVector(x0));
3329 double *x1_data = hypre_VectorData(hypre_ParVectorLocalVector(x1));
3330 double *x2_data = hypre_VectorData(hypre_ParVectorLocalVector(x2));
3331 double *x3_data = hypre_VectorData(hypre_ParVectorLocalVector(x3));
3333 hypre_ParVectorCopy(
u, x0);
3336 hypre_ParVectorCopy(
f, x1);
3337 hypre_ParCSRMatrixMatvec(-1.0, A, x0, 1.0, x1);
3339 for (HYPRE_Int i = 0; i < num_rows; i++)
3341 x1_data[i] /= -max_eig;
3345 for (HYPRE_Int i = 0; i < num_rows; i++)
3347 x1_data[i] = x0_data[i] -x1_data[i];
3351 for (HYPRE_Int i = 0; i < num_rows; i++)
3353 x3_data[i] = fir_coeffs[0]*x0_data[i] +fir_coeffs[1]*x1_data[i];
3356 for (
int n = 2; n <= poly_order; n++)
3359 hypre_ParVectorCopy(
f, x2);
3360 hypre_ParCSRMatrixMatvec(-1.0, A, x1, 1.0, x2);
3362 for (HYPRE_Int i = 0; i < num_rows; i++)
3364 x2_data[i] /= -max_eig;
3372 for (HYPRE_Int i = 0; i < num_rows; i++)
3374 x2_data[i] = (x1_data[i]-x0_data[i]) +(x1_data[i]-2*x2_data[i]);
3375 x3_data[i] += fir_coeffs[n]*x2_data[i];
3376 x0_data[i] = x1_data[i];
3377 x1_data[i] = x2_data[i];
3381 for (HYPRE_Int i = 0; i < num_rows; i++)
3383 u_data[i] = x3_data[i];
3404 B =
X =
V =
Z = NULL;
3412 int relax_times_,
double relax_weight_,
3413 double omega_,
int poly_order_,
3414 double poly_fraction_,
int eig_est_cg_iter_)
3426 B =
X =
V =
Z = NULL;
3437 type =
static_cast<int>(type_);
3448 int eig_est_cg_iter_)
3465 double a = -1,
b, c;
3466 if (!strcmp(name,
"Rectangular")) {
a = 1.0,
b = 0.0, c = 0.0; }
3467 if (!strcmp(name,
"Hanning")) {
a = 0.5,
b = 0.5, c = 0.0; }
3468 if (!strcmp(name,
"Hamming")) {
a = 0.54,
b = 0.46, c = 0.0; }
3469 if (!strcmp(name,
"Blackman")) {
a = 0.42,
b = 0.50, c = 0.08; }
3472 mfem_error(
"HypreSmoother::SetWindowByName : name not recognized!");
3490 mfem_error(
"HypreSmoother::SetOperator : not HypreParMatrix!");
3497 if (
B) {
delete B; }
3498 if (
X) {
delete X; }
3499 if (
V) {
delete V; }
3500 if (
Z) {
delete Z; }
3522 A->
Mult(ones, diag);
3530 #if defined(HYPRE_USING_GPU) 3532 MFEM_GPU_FORALL(i,
height,
3534 d_l1_norms[i] = std::abs(d_l1_norms[i]);
3537 for (
int i = 0; i <
height; i++)
3554 #if MFEM_HYPRE_VERSION <= 22200 3563 else if (
type == 1001 ||
type == 1002)
3573 #if MFEM_HYPRE_VERSION <= 22200 3606 double* window_coeffs =
new double[
poly_order+1];
3607 double* cheby_coeffs =
new double[
poly_order+1];
3615 window_coeffs[i] =
a +
b*cos(
t) +c*cos(2*
t);
3619 double theta_pb = acos(1.0 -0.5*k_pb);
3621 cheby_coeffs[0] = (theta_pb +
sigma)/M_PI;
3624 double t = i*(theta_pb+
sigma);
3625 cheby_coeffs[i] = 2.0*sin(
t)/(i*M_PI);
3630 fir_coeffs[i] = window_coeffs[i]*cheby_coeffs[i];
3633 delete[] window_coeffs;
3634 delete[] cheby_coeffs;
3641 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
3654 HYPRE_ParCSRDiagScale(NULL, *
A,
b, x);
3661 hypre_ParVectorSetConstantValues(x, 0.0);
3682 else if (
type == 1002)
3696 int hypre_type =
type;
3698 if (
type == 5) { hypre_type = 1; }
3702 hypre_ParCSRRelax(*
A,
b, hypre_type,
3709 hypre_ParCSRRelax(*
A,
b, hypre_type,
3719 MFEM_ASSERT(
b.Size() ==
NumCols(),
"");
3724 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
3731 A -> GetGlobalNumRows(),
3733 A -> GetRowStarts());
3735 A -> GetGlobalNumCols(),
3737 A -> GetColStarts());
3775 if (!xshallow) { x = *
X; }
3785 mfem_error(
"HypreSmoother::MultTranspose (...) : undefined!\n");
3791 if (
B) {
delete B; }
3792 if (
X) {
delete X; }
3793 if (
V) {
delete V; }
3794 if (
Z) {
delete Z; }
3803 if (
X0) {
delete X0; }
3804 if (
X1) {
delete X1; }
3819 :
Solver(A_->Height(), A_->Width())
3831 MFEM_ASSERT(
b.Size() ==
NumCols(),
"");
3834 MFEM_VERIFY(
A != NULL,
"HypreParMatrix A is missing");
3884 MFEM_VERIFY(
A != NULL,
"HypreParMatrix A is missing");
3886 HYPRE_Int err_flag =
SetupFcn()(*
this, *
A,
b, x);
3890 { MFEM_WARNING(
"Error during setup! Error code: " << err_flag); }
3894 MFEM_VERIFY(!err_flag,
"Error during setup! Error code: " << err_flag);
3896 hypre_error_flag = 0;
3904 if (!x_shallow) { x = *
X; }
3912 mfem_error(
"HypreSolver::Mult (...) : HypreParMatrix A is missing");
3919 hypre_ParVectorSetConstantValues(x, 0.0);
3931 { MFEM_WARNING(
"Error during solve! Error code: " << err_flag); }
3935 MFEM_VERIFY(!err_flag,
"Error during solve! Error code: " << err_flag);
3937 hypre_error_flag = 0;
3944 if (!x_shallow) { x = *
X; }
3949 if (
B) {
delete B; }
3950 if (
X) {
delete X; }
3960 HYPRE_ParCSRPCGCreate(comm, &pcg_solver);
3969 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
3971 HYPRE_ParCSRPCGCreate(comm, &pcg_solver);
3977 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3998 HYPRE_PCGSetTol(pcg_solver, tol);
4003 HYPRE_PCGSetAbsoluteTol(pcg_solver, atol);
4008 HYPRE_PCGSetMaxIter(pcg_solver, max_iter);
4013 HYPRE_PCGSetLogging(pcg_solver, logging);
4018 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_lvl);
4023 precond = &precond_;
4025 HYPRE_ParCSRPCGSetPrecond(pcg_solver,
4033 HYPRE_PCGSetTwoNorm(pcg_solver, 1);
4034 if (res_frequency > 0)
4036 HYPRE_PCGSetRecomputeResidualP(pcg_solver, res_frequency);
4040 HYPRE_PCGSetResidualTol(pcg_solver, rtol);
4047 HYPRE_Int time_index = 0;
4048 HYPRE_Int num_iterations;
4049 double final_res_norm;
4051 HYPRE_Int print_level;
4053 HYPRE_PCGGetPrintLevel(pcg_solver, &print_level);
4054 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level%3);
4056 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
4061 hypre_ParVectorSetConstantValues(x, 0.0);
4069 if (print_level > 0 && print_level < 3)
4071 time_index = hypre_InitializeTiming(
"PCG Setup");
4072 hypre_BeginTiming(time_index);
4075 HYPRE_ParCSRPCGSetup(pcg_solver, *
A,
b, x);
4078 if (print_level > 0 && print_level < 3)
4080 hypre_EndTiming(time_index);
4081 hypre_PrintTiming(
"Setup phase times", comm);
4082 hypre_FinalizeTiming(time_index);
4083 hypre_ClearTiming();
4087 if (print_level > 0 && print_level < 3)
4089 time_index = hypre_InitializeTiming(
"PCG Solve");
4090 hypre_BeginTiming(time_index);
4093 HYPRE_ParCSRPCGSolve(pcg_solver, *
A,
b, x);
4095 if (print_level > 0)
4097 if (print_level < 3)
4099 hypre_EndTiming(time_index);
4100 hypre_PrintTiming(
"Solve phase times", comm);
4101 hypre_FinalizeTiming(time_index);
4102 hypre_ClearTiming();
4105 HYPRE_ParCSRPCGGetNumIterations(pcg_solver, &num_iterations);
4106 HYPRE_ParCSRPCGGetFinalRelativeResidualNorm(pcg_solver,
4109 MPI_Comm_rank(comm, &myid);
4113 mfem::out <<
"PCG Iterations = " << num_iterations << endl
4114 <<
"Final PCG Relative Residual Norm = " << final_res_norm
4118 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level);
4123 HYPRE_ParCSRPCGDestroy(pcg_solver);
4131 HYPRE_ParCSRGMRESCreate(comm, &gmres_solver);
4132 SetDefaultOptions();
4142 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
4144 HYPRE_ParCSRGMRESCreate(comm, &gmres_solver);
4145 SetDefaultOptions();
4148 void HypreGMRES::SetDefaultOptions()
4154 HYPRE_ParCSRGMRESSetKDim(gmres_solver, k_dim);
4155 HYPRE_ParCSRGMRESSetMaxIter(gmres_solver, max_iter);
4156 HYPRE_ParCSRGMRESSetTol(gmres_solver, tol);
4162 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4183 HYPRE_GMRESSetTol(gmres_solver, tol);
4188 HYPRE_GMRESSetAbsoluteTol(gmres_solver, tol);
4193 HYPRE_GMRESSetMaxIter(gmres_solver, max_iter);
4198 HYPRE_GMRESSetKDim(gmres_solver, k_dim);
4203 HYPRE_GMRESSetLogging(gmres_solver, logging);
4208 HYPRE_GMRESSetPrintLevel(gmres_solver, print_lvl);
4213 precond = &precond_;
4215 HYPRE_ParCSRGMRESSetPrecond(gmres_solver,
4224 HYPRE_Int time_index = 0;
4225 HYPRE_Int num_iterations;
4226 double final_res_norm;
4228 HYPRE_Int print_level;
4230 HYPRE_GMRESGetPrintLevel(gmres_solver, &print_level);
4232 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
4237 hypre_ParVectorSetConstantValues(x, 0.0);
4245 if (print_level > 0)
4247 time_index = hypre_InitializeTiming(
"GMRES Setup");
4248 hypre_BeginTiming(time_index);
4251 HYPRE_ParCSRGMRESSetup(gmres_solver, *
A,
b, x);
4254 if (print_level > 0)
4256 hypre_EndTiming(time_index);
4257 hypre_PrintTiming(
"Setup phase times", comm);
4258 hypre_FinalizeTiming(time_index);
4259 hypre_ClearTiming();
4263 if (print_level > 0)
4265 time_index = hypre_InitializeTiming(
"GMRES Solve");
4266 hypre_BeginTiming(time_index);
4269 HYPRE_ParCSRGMRESSolve(gmres_solver, *
A,
b, x);
4271 if (print_level > 0)
4273 hypre_EndTiming(time_index);
4274 hypre_PrintTiming(
"Solve phase times", comm);
4275 hypre_FinalizeTiming(time_index);
4276 hypre_ClearTiming();
4278 HYPRE_ParCSRGMRESGetNumIterations(gmres_solver, &num_iterations);
4279 HYPRE_ParCSRGMRESGetFinalRelativeResidualNorm(gmres_solver,
4282 MPI_Comm_rank(comm, &myid);
4286 mfem::out <<
"GMRES Iterations = " << num_iterations << endl
4287 <<
"Final GMRES Relative Residual Norm = " << final_res_norm
4295 HYPRE_ParCSRGMRESDestroy(gmres_solver);
4303 HYPRE_ParCSRFlexGMRESCreate(comm, &fgmres_solver);
4304 SetDefaultOptions();
4314 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
4316 HYPRE_ParCSRFlexGMRESCreate(comm, &fgmres_solver);
4317 SetDefaultOptions();
4320 void HypreFGMRES::SetDefaultOptions()
4326 HYPRE_ParCSRFlexGMRESSetKDim(fgmres_solver, k_dim);
4327 HYPRE_ParCSRFlexGMRESSetMaxIter(fgmres_solver, max_iter);
4328 HYPRE_ParCSRFlexGMRESSetTol(fgmres_solver, tol);
4334 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4355 HYPRE_ParCSRFlexGMRESSetTol(fgmres_solver, tol);
4360 HYPRE_ParCSRFlexGMRESSetMaxIter(fgmres_solver, max_iter);
4365 HYPRE_ParCSRFlexGMRESSetKDim(fgmres_solver, k_dim);
4370 HYPRE_ParCSRFlexGMRESSetLogging(fgmres_solver, logging);
4375 HYPRE_ParCSRFlexGMRESSetPrintLevel(fgmres_solver, print_lvl);
4380 precond = &precond_;
4381 HYPRE_ParCSRFlexGMRESSetPrecond(fgmres_solver,
4390 HYPRE_Int time_index = 0;
4391 HYPRE_Int num_iterations;
4392 double final_res_norm;
4394 HYPRE_Int print_level;
4396 HYPRE_FlexGMRESGetPrintLevel(fgmres_solver, &print_level);
4398 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
4403 hypre_ParVectorSetConstantValues(x, 0.0);
4411 if (print_level > 0)
4413 time_index = hypre_InitializeTiming(
"FGMRES Setup");
4414 hypre_BeginTiming(time_index);
4417 HYPRE_ParCSRFlexGMRESSetup(fgmres_solver, *
A,
b, x);
4420 if (print_level > 0)
4422 hypre_EndTiming(time_index);
4423 hypre_PrintTiming(
"Setup phase times", comm);
4424 hypre_FinalizeTiming(time_index);
4425 hypre_ClearTiming();
4429 if (print_level > 0)
4431 time_index = hypre_InitializeTiming(
"FGMRES Solve");
4432 hypre_BeginTiming(time_index);
4435 HYPRE_ParCSRFlexGMRESSolve(fgmres_solver, *
A,
b, x);
4437 if (print_level > 0)
4439 hypre_EndTiming(time_index);
4440 hypre_PrintTiming(
"Solve phase times", comm);
4441 hypre_FinalizeTiming(time_index);
4442 hypre_ClearTiming();
4444 HYPRE_ParCSRFlexGMRESGetNumIterations(fgmres_solver, &num_iterations);
4445 HYPRE_ParCSRFlexGMRESGetFinalRelativeResidualNorm(fgmres_solver,
4448 MPI_Comm_rank(comm, &myid);
4452 mfem::out <<
"FGMRES Iterations = " << num_iterations << endl
4453 <<
"Final FGMRES Relative Residual Norm = " << final_res_norm
4461 HYPRE_ParCSRFlexGMRESDestroy(fgmres_solver);
4468 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4485 HYPRE_ParaSailsCreate(comm, &sai_precond);
4486 SetDefaultOptions();
4493 HYPRE_ParCSRMatrixGetComm(
A, &comm);
4495 HYPRE_ParaSailsCreate(comm, &sai_precond);
4496 SetDefaultOptions();
4499 void HypreParaSails::SetDefaultOptions()
4501 int sai_max_levels = 1;
4502 double sai_threshold = 0.1;
4503 double sai_filter = 0.1;
4505 double sai_loadbal = 0.0;
4507 int sai_logging = 1;
4509 HYPRE_ParaSailsSetParams(sai_precond, sai_threshold, sai_max_levels);
4510 HYPRE_ParaSailsSetFilter(sai_precond, sai_filter);
4511 HYPRE_ParaSailsSetSym(sai_precond, sai_sym);
4512 HYPRE_ParaSailsSetLoadbal(sai_precond, sai_loadbal);
4513 HYPRE_ParaSailsSetReuse(sai_precond, sai_reuse);
4514 HYPRE_ParaSailsSetLogging(sai_precond, sai_logging);
4517 void HypreParaSails::ResetSAIPrecond(MPI_Comm comm)
4519 HYPRE_Int sai_max_levels;
4520 HYPRE_Real sai_threshold;
4521 HYPRE_Real sai_filter;
4523 HYPRE_Real sai_loadbal;
4524 HYPRE_Int sai_reuse;
4525 HYPRE_Int sai_logging;
4528 HYPRE_ParaSailsGetNlevels(sai_precond, &sai_max_levels);
4529 HYPRE_ParaSailsGetThresh(sai_precond, &sai_threshold);
4530 HYPRE_ParaSailsGetFilter(sai_precond, &sai_filter);
4531 HYPRE_ParaSailsGetSym(sai_precond, &sai_sym);
4532 HYPRE_ParaSailsGetLoadbal(sai_precond, &sai_loadbal);
4533 HYPRE_ParaSailsGetReuse(sai_precond, &sai_reuse);
4534 HYPRE_ParaSailsGetLogging(sai_precond, &sai_logging);
4536 HYPRE_ParaSailsDestroy(sai_precond);
4537 HYPRE_ParaSailsCreate(comm, &sai_precond);
4539 HYPRE_ParaSailsSetParams(sai_precond, sai_threshold, sai_max_levels);
4540 HYPRE_ParaSailsSetFilter(sai_precond, sai_filter);
4541 HYPRE_ParaSailsSetSym(sai_precond, sai_sym);
4542 HYPRE_ParaSailsSetLoadbal(sai_precond, sai_loadbal);
4543 HYPRE_ParaSailsSetReuse(sai_precond, sai_reuse);
4544 HYPRE_ParaSailsSetLogging(sai_precond, sai_logging);
4550 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4555 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
4556 ResetSAIPrecond(comm);
4573 HYPRE_ParaSailsSetParams(sai_precond, threshold, max_levels);
4578 HYPRE_ParaSailsSetFilter(sai_precond, filter);
4583 HYPRE_ParaSailsSetLoadbal(sai_precond, loadbal);
4588 HYPRE_ParaSailsSetReuse(sai_precond, reuse);
4593 HYPRE_ParaSailsSetLogging(sai_precond, logging);
4598 HYPRE_ParaSailsSetSym(sai_precond, sym);
4603 HYPRE_ParaSailsDestroy(sai_precond);
4609 HYPRE_EuclidCreate(comm, &euc_precond);
4610 SetDefaultOptions();
4617 HYPRE_ParCSRMatrixGetComm(
A, &comm);
4619 HYPRE_EuclidCreate(comm, &euc_precond);
4620 SetDefaultOptions();
4623 void HypreEuclid::SetDefaultOptions()
4631 HYPRE_EuclidSetLevel(euc_precond, euc_level);
4632 HYPRE_EuclidSetStats(euc_precond, euc_stats);
4633 HYPRE_EuclidSetMem(euc_precond, euc_mem);
4634 HYPRE_EuclidSetBJ(euc_precond, euc_bj);
4635 HYPRE_EuclidSetRowScale(euc_precond, euc_ro_sc);
4640 HYPRE_EuclidSetLevel(euc_precond, level);
4645 HYPRE_EuclidSetStats(euc_precond, stats);
4650 HYPRE_EuclidSetMem(euc_precond, mem);
4655 HYPRE_EuclidSetBJ(euc_precond, bj);
4660 HYPRE_EuclidSetRowScale(euc_precond, row_scale);
4663 void HypreEuclid::ResetEuclidPrecond(MPI_Comm comm)
4667 HYPRE_EuclidDestroy(euc_precond);
4668 HYPRE_EuclidCreate(comm, &euc_precond);
4670 SetDefaultOptions();
4676 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4681 HYPRE_ParCSRMatrixGetComm(*new_A, &comm);
4682 ResetEuclidPrecond(comm);
4699 HYPRE_EuclidDestroy(euc_precond);
4703 #if MFEM_HYPRE_VERSION >= 21900 4706 HYPRE_ILUCreate(&ilu_precond);
4707 SetDefaultOptions();
4710 void HypreILU::SetDefaultOptions()
4713 HYPRE_Int ilu_type = 0;
4714 HYPRE_ILUSetType(ilu_precond, ilu_type);
4717 HYPRE_Int max_iter = 1;
4718 HYPRE_ILUSetMaxIter(ilu_precond, max_iter);
4721 HYPRE_Real tol = 0.0;
4722 HYPRE_ILUSetTol(ilu_precond, tol);
4725 HYPRE_Int lev_fill = 1;
4726 HYPRE_ILUSetLevelOfFill(ilu_precond, lev_fill);
4729 HYPRE_Int reorder_type = 1;
4730 HYPRE_ILUSetLocalReordering(ilu_precond, reorder_type);
4733 HYPRE_Int print_level = 0;
4734 HYPRE_ILUSetPrintLevel(ilu_precond, print_level);
4737 void HypreILU::ResetILUPrecond()
4741 HYPRE_ILUDestroy(ilu_precond);
4743 HYPRE_ILUCreate(&ilu_precond);
4744 SetDefaultOptions();
4749 HYPRE_ILUSetLevelOfFill(ilu_precond, lev_fill);
4754 HYPRE_ILUSetType(ilu_precond, ilu_type);
4759 HYPRE_ILUSetMaxIter(ilu_precond, max_iter);
4764 HYPRE_ILUSetTol(ilu_precond, tol);
4769 HYPRE_ILUSetLocalReordering(ilu_precond, reorder_type);
4774 HYPRE_ILUSetPrintLevel(ilu_precond, print_level);
4780 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4782 if (
A) { ResetILUPrecond(); }
4798 HYPRE_ILUDestroy(ilu_precond);
4805 HYPRE_BoomerAMGCreate(&amg_precond);
4806 SetDefaultOptions();
4811 HYPRE_BoomerAMGCreate(&amg_precond);
4812 SetDefaultOptions();
4815 void HypreBoomerAMG::SetDefaultOptions()
4817 #if !defined(HYPRE_USING_GPU) 4819 int coarsen_type = 10;
4821 double theta = 0.25;
4824 int interp_type = 6;
4829 int relax_sweeps = 1;
4832 int print_level = 1;
4833 int max_levels = 25;
4836 int coarsen_type = 8;
4838 double theta = 0.25;
4841 int interp_type = 6;
4845 int relax_type = 18;
4846 int relax_sweeps = 1;
4849 int print_level = 1;
4850 int max_levels = 25;
4853 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
4854 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
4855 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
4858 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
4859 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
4860 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
4861 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
4862 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
4863 HYPRE_BoomerAMGSetMaxLevels(amg_precond, max_levels);
4866 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
4867 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
4870 void HypreBoomerAMG::ResetAMGPrecond()
4872 HYPRE_Int coarsen_type;
4873 HYPRE_Int agg_levels;
4874 HYPRE_Int relax_type;
4875 HYPRE_Int relax_sweeps;
4877 HYPRE_Int interp_type;
4879 HYPRE_Int print_level;
4880 HYPRE_Int max_levels;
4882 HYPRE_Int nrbms = rbms.
Size();
4884 HYPRE_Int nodal_diag;
4885 HYPRE_Int relax_coarse;
4886 HYPRE_Int interp_vec_variant;
4888 HYPRE_Int smooth_interp_vectors;
4889 HYPRE_Int interp_refine;
4891 hypre_ParAMGData *amg_data = (hypre_ParAMGData *)amg_precond;
4894 HYPRE_BoomerAMGGetCoarsenType(amg_precond, &coarsen_type);
4895 agg_levels = hypre_ParAMGDataAggNumLevels(amg_data);
4896 relax_type = hypre_ParAMGDataUserRelaxType(amg_data);
4897 relax_sweeps = hypre_ParAMGDataUserNumSweeps(amg_data);
4898 HYPRE_BoomerAMGGetStrongThreshold(amg_precond, &theta);
4899 hypre_BoomerAMGGetInterpType(amg_precond, &interp_type);
4900 HYPRE_BoomerAMGGetPMaxElmts(amg_precond, &Pmax);
4901 HYPRE_BoomerAMGGetPrintLevel(amg_precond, &print_level);
4902 HYPRE_BoomerAMGGetMaxLevels(amg_precond, &max_levels);
4903 HYPRE_BoomerAMGGetNumFunctions(amg_precond, &
dim);
4906 nodal = hypre_ParAMGDataNodal(amg_data);
4907 nodal_diag = hypre_ParAMGDataNodalDiag(amg_data);
4908 HYPRE_BoomerAMGGetCycleRelaxType(amg_precond, &relax_coarse, 3);
4909 interp_vec_variant = hypre_ParAMGInterpVecVariant(amg_data);
4910 q_max = hypre_ParAMGInterpVecQMax(amg_data);
4911 smooth_interp_vectors = hypre_ParAMGSmoothInterpVectors(amg_data);
4912 interp_refine = hypre_ParAMGInterpRefine(amg_data);
4915 HYPRE_BoomerAMGDestroy(amg_precond);
4916 HYPRE_BoomerAMGCreate(&amg_precond);
4918 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
4919 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
4920 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
4921 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
4922 HYPRE_BoomerAMGSetMaxLevels(amg_precond, max_levels);
4923 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
4924 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
4925 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
4926 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
4927 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
4928 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
4929 HYPRE_BoomerAMGSetNumFunctions(amg_precond,
dim);
4932 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
4933 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
4934 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
4935 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
4936 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
4937 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
4938 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
4940 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
4947 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4949 if (
A) { ResetAMGPrecond(); }
4965 HYPRE_BoomerAMGSetNumFunctions(amg_precond,
dim);
4973 HYPRE_Int *h_mapping = mfem_hypre_CTAlloc_host(HYPRE_Int,
height);
4975 MFEM_VERIFY(
height %
dim == 0,
"Ordering does not work as claimed!");
4977 for (
int i = 0; i <
dim; ++i)
4979 for (
int j = 0; j < h_nnodes; ++j)
4988 #if defined(hypre_IntArrayData) && defined(HYPRE_USING_GPU) 4989 HYPRE_Int *mapping = mfem_hypre_CTAlloc(HYPRE_Int,
height);
4990 hypre_TMemcpy(mapping, h_mapping, HYPRE_Int,
height,
4991 HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
4992 mfem_hypre_TFree_host(h_mapping);
4994 HYPRE_Int *mapping = h_mapping;
4999 HYPRE_BoomerAMGSetDofFunc(amg_precond, mapping);
5003 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, 0);
5004 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, 0.5);
5010 y = 0.0; y(0) = x(1); y(1) = -x(0);
5012 static void func_ryz(
const Vector &x, Vector &y)
5014 y = 0.0; y(1) = x(2); y(2) = -x(1);
5016 static void func_rzx(
const Vector &x, Vector &y)
5018 y = 0.0; y(2) = x(0); y(0) = -x(2);
5021 void HypreBoomerAMG::RecomputeRBMs()
5024 Array<HypreParVector*> gf_rbms;
5027 for (
int i = 0; i < rbms.
Size(); i++)
5029 HYPRE_ParVectorDestroy(rbms[i]);
5036 VectorFunctionCoefficient coeff_rxy(2, func_rxy);
5038 ParGridFunction rbms_rxy(fespace);
5039 rbms_rxy.ProjectCoefficient(coeff_rxy);
5042 gf_rbms.SetSize(nrbms);
5044 rbms_rxy.GetTrueDofs(*gf_rbms[0]);
5050 VectorFunctionCoefficient coeff_rxy(3, func_rxy);
5051 VectorFunctionCoefficient coeff_ryz(3, func_ryz);
5052 VectorFunctionCoefficient coeff_rzx(3, func_rzx);
5054 ParGridFunction rbms_rxy(fespace);
5055 ParGridFunction rbms_ryz(fespace);
5056 ParGridFunction rbms_rzx(fespace);
5057 rbms_rxy.ProjectCoefficient(coeff_rxy);
5058 rbms_ryz.ProjectCoefficient(coeff_ryz);
5059 rbms_rzx.ProjectCoefficient(coeff_rzx);
5062 gf_rbms.SetSize(nrbms);
5066 rbms_rxy.GetTrueDofs(*gf_rbms[0]);
5067 rbms_ryz.GetTrueDofs(*gf_rbms[1]);
5068 rbms_rzx.GetTrueDofs(*gf_rbms[2]);
5077 for (
int i = 0; i < nrbms; i++)
5079 rbms[i] = gf_rbms[i]->StealParVector();
5086 #ifdef HYPRE_USING_GPU 5087 MFEM_ABORT(
"this method is not supported in hypre built with GPU support");
5091 this->fespace = fespace_;
5101 int relax_coarse = 8;
5104 int interp_vec_variant = 2;
5106 int smooth_interp_vectors = 1;
5110 int interp_refine = 1;
5112 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
5113 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
5114 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
5115 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
5116 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
5117 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
5118 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
5121 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
5130 #if MFEM_HYPRE_VERSION >= 21800 5133 const std::string &prerelax,
5134 const std::string &postrelax)
5138 int interp_type = 100;
5139 int relax_type = 10;
5140 int coarsen_type = 6;
5141 double strength_tolC = 0.1;
5142 double strength_tolR = 0.01;
5143 double filter_tolR = 0.0;
5144 double filterA_tol = 0.0;
5147 int ns_down, ns_up, ns_coarse;
5150 ns_down = prerelax.length();
5151 ns_up = postrelax.length();
5155 HYPRE_Int **grid_relax_points = mfem_hypre_TAlloc(HYPRE_Int*, 4);
5156 grid_relax_points[0] = NULL;
5157 grid_relax_points[1] = mfem_hypre_TAlloc(HYPRE_Int, ns_down);
5158 grid_relax_points[2] = mfem_hypre_TAlloc(HYPRE_Int, ns_up);
5159 grid_relax_points[3] = mfem_hypre_TAlloc(HYPRE_Int, 1);
5160 grid_relax_points[3][0] = 0;
5163 for (
int i = 0; i<ns_down; i++)
5165 if (prerelax[i] ==
'F')
5167 grid_relax_points[1][i] = -1;
5169 else if (prerelax[i] ==
'C')
5171 grid_relax_points[1][i] = 1;
5173 else if (prerelax[i] ==
'A')
5175 grid_relax_points[1][i] = 0;
5180 for (
int i = 0; i<ns_up; i++)
5182 if (postrelax[i] ==
'F')
5184 grid_relax_points[2][i] = -1;
5186 else if (postrelax[i] ==
'C')
5188 grid_relax_points[2][i] = 1;
5190 else if (postrelax[i] ==
'A')
5192 grid_relax_points[2][i] = 0;
5196 HYPRE_BoomerAMGSetRestriction(amg_precond, distanceR);
5198 HYPRE_BoomerAMGSetGridRelaxPoints(amg_precond, grid_relax_points);
5200 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
5205 HYPRE_BoomerAMGSetSabs(amg_precond, Sabs);
5208 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
5211 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, 0);
5213 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, strength_tolC);
5217 HYPRE_BoomerAMGSetStrongThresholdR(amg_precond, strength_tolR);
5218 HYPRE_BoomerAMGSetFilterThresholdR(amg_precond, filter_tolR);
5221 if (relax_type > -1)
5223 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
5228 HYPRE_BoomerAMGSetCycleNumSweeps(amg_precond, ns_coarse, 3);
5229 HYPRE_BoomerAMGSetCycleNumSweeps(amg_precond, ns_down, 1);
5230 HYPRE_BoomerAMGSetCycleNumSweeps(amg_precond, ns_up, 2);
5232 HYPRE_BoomerAMGSetADropTol(amg_precond, filterA_tol);
5234 HYPRE_BoomerAMGSetADropType(amg_precond, -1);
5242 for (
int i = 0; i < rbms.
Size(); i++)
5244 HYPRE_ParVectorDestroy(rbms[i]);
5247 HYPRE_BoomerAMGDestroy(amg_precond);
5273 MFEM_ASSERT(G != NULL,
"");
5274 MFEM_ASSERT(x != NULL,
"");
5275 MFEM_ASSERT(y != NULL,
"");
5276 int sdim = (z == NULL) ? 2 : 3;
5277 int cycle_type = 13;
5279 MakeSolver(sdim, cycle_type);
5281 HYPRE_ParVector pz = z ?
static_cast<HYPRE_ParVector
>(*z) : NULL;
5282 HYPRE_AMSSetCoordinateVectors(ams, *x, *y, pz);
5283 HYPRE_AMSSetDiscreteGradient(ams, *G);
5286 void HypreAMS::MakeSolver(
int sdim,
int cycle_type)
5289 double rlx_weight = 1.0;
5290 double rlx_omega = 1.0;
5291 #if !defined(HYPRE_USING_GPU) 5292 int amg_coarsen_type = 10;
5293 int amg_agg_levels = 1;
5294 int amg_rlx_type = 8;
5296 double theta = 0.25;
5297 int amg_interp_type = 6;
5300 int amg_coarsen_type = 8;
5301 int amg_agg_levels = 0;
5302 int amg_rlx_type = 18;
5304 double theta = 0.25;
5305 int amg_interp_type = 6;
5310 ams_cycle_type = cycle_type;
5311 HYPRE_AMSCreate(&ams);
5313 HYPRE_AMSSetDimension(ams, sdim);
5314 HYPRE_AMSSetTol(ams, 0.0);
5315 HYPRE_AMSSetMaxIter(ams, 1);
5316 HYPRE_AMSSetCycleType(ams, cycle_type);
5317 HYPRE_AMSSetPrintLevel(ams, 1);
5320 HYPRE_AMSSetSmoothingOptions(ams, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
5321 HYPRE_AMSSetAlphaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
5322 theta, amg_interp_type, amg_Pmax);
5323 HYPRE_AMSSetBetaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
5324 theta, amg_interp_type, amg_Pmax);
5326 HYPRE_AMSSetAlphaAMGCoarseRelaxType(ams, amg_rlx_type);
5327 HYPRE_AMSSetBetaAMGCoarseRelaxType(ams, amg_rlx_type);
5336 void HypreAMS::MakeGradientAndInterpolation(
5337 ParFiniteElementSpace *edge_fespace,
int cycle_type)
5339 int dim = edge_fespace->GetMesh()->Dimension();
5340 int sdim = edge_fespace->GetMesh()->SpaceDimension();
5341 const FiniteElementCollection *edge_fec = edge_fespace->FEColl();
5343 bool trace_space, rt_trace_space;
5344 ND_Trace_FECollection *nd_tr_fec = NULL;
5345 trace_space =
dynamic_cast<const ND_Trace_FECollection*
>(edge_fec);
5346 rt_trace_space =
dynamic_cast<const RT_Trace_FECollection*
>(edge_fec);
5347 trace_space = trace_space || rt_trace_space;
5350 if (edge_fespace->GetNE() > 0)
5352 MFEM_VERIFY(!edge_fespace->IsVariableOrder(),
"");
5355 p = edge_fespace->GetFaceOrder(0);
5356 if (
dim == 2) {
p++; }
5360 p = edge_fespace->GetElementOrder(0);
5364 ParMesh *pmesh = edge_fespace->GetParMesh();
5367 nd_tr_fec =
new ND_Trace_FECollection(
p,
dim);
5368 edge_fespace =
new ParFiniteElementSpace(pmesh, nd_tr_fec);
5372 FiniteElementCollection *vert_fec;
5375 vert_fec =
new H1_Trace_FECollection(
p,
dim);
5379 vert_fec =
new H1_FECollection(
p,
dim);
5381 ParFiniteElementSpace *vert_fespace =
new ParFiniteElementSpace(pmesh,
5385 if (
p == 1 && pmesh->GetNodes() == NULL)
5387 ParGridFunction x_coord(vert_fespace);
5388 ParGridFunction y_coord(vert_fespace);
5389 ParGridFunction z_coord(vert_fespace);
5391 for (
int i = 0; i < pmesh->GetNV(); i++)
5393 coord = pmesh -> GetVertex(i);
5394 x_coord(i) = coord[0];
5395 if (sdim >= 2) { y_coord(i) = coord[1]; }
5396 if (sdim == 3) { z_coord(i) = coord[2]; }
5398 x = x_coord.ParallelProject();
5405 y = y_coord.ParallelProject();
5410 z = z_coord.ParallelProject();
5414 HYPRE_AMSSetCoordinateVectors(ams,
5415 x ? (HYPRE_ParVector)(*x) : NULL,
5416 y ? (HYPRE_ParVector)(*y) : NULL,
5417 z ? (HYPRE_ParVector)(*z) : NULL);
5427 ParDiscreteLinearOperator *grad;
5428 grad =
new ParDiscreteLinearOperator(vert_fespace, edge_fespace);
5431 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
5435 grad->AddDomainInterpolator(
new GradientInterpolator);
5439 G = grad->ParallelAssemble();
5440 HYPRE_AMSSetDiscreteGradient(ams, *G);
5444 Pi = Pix = Piy = Piz = NULL;
5445 if (
p > 1 || pmesh->GetNodes() != NULL)
5447 ParFiniteElementSpace *vert_fespace_d
5450 ParDiscreteLinearOperator *id_ND;
5451 id_ND =
new ParDiscreteLinearOperator(vert_fespace_d, edge_fespace);
5454 id_ND->AddTraceFaceInterpolator(
new IdentityInterpolator);
5458 id_ND->AddDomainInterpolator(
new IdentityInterpolator);
5463 if (cycle_type < 10)
5465 Pi = id_ND->ParallelAssemble();
5469 Array2D<HypreParMatrix *> Pi_blocks;
5470 id_ND->GetParBlocks(Pi_blocks);
5471 Pix = Pi_blocks(0,0);
5472 if (sdim >= 2) { Piy = Pi_blocks(0,1); }
5473 if (sdim == 3) { Piz = Pi_blocks(0,2); }
5478 HYPRE_ParCSRMatrix HY_Pi = (Pi) ? (HYPRE_ParCSRMatrix) *Pi : NULL;
5479 HYPRE_ParCSRMatrix HY_Pix = (Pix) ? (HYPRE_ParCSRMatrix) *Pix : NULL;
5480 HYPRE_ParCSRMatrix HY_Piy = (Piy) ? (HYPRE_ParCSRMatrix) *Piy : NULL;
5481 HYPRE_ParCSRMatrix HY_Piz = (Piz) ? (HYPRE_ParCSRMatrix) *Piz : NULL;
5482 HYPRE_AMSSetInterpolations(ams, HY_Pi, HY_Pix, HY_Piy, HY_Piz);
5484 delete vert_fespace_d;
5487 delete vert_fespace;
5492 delete edge_fespace;
5497 void HypreAMS::Init(ParFiniteElementSpace *edge_fespace)
5499 int cycle_type = 13;
5500 int sdim = edge_fespace->GetMesh()->SpaceDimension();
5501 MakeSolver(sdim, cycle_type);
5502 MakeGradientAndInterpolation(edge_fespace, cycle_type);
5505 void HypreAMS::ResetAMSPrecond()
5507 #if MFEM_HYPRE_VERSION >= 22600 5509 auto *ams_data = (hypre_AMSData *)ams;
5512 HYPRE_Int
dim = hypre_AMSDataDimension(ams_data);
5515 hypre_ParCSRMatrix *hy_G = hypre_AMSDataDiscreteGradient(ams_data);
5517 HYPRE_Int beta_is_zero = hypre_AMSDataBetaIsZero(ams_data);
5520 hypre_ParCSRMatrix *hy_Pi hypre_AMSDataPiInterpolation(ams_data);
5521 hypre_ParCSRMatrix *hy_Pix = ams_data->Pix;
5522 hypre_ParCSRMatrix *hy_Piy = ams_data->Piy;
5523 hypre_ParCSRMatrix *hy_Piz = ams_data->Piz;
5524 HYPRE_Int owns_Pi = hypre_AMSDataOwnsPiInterpolation(ams_data);
5527 ams_data->owns_Pi = 0;
5531 hypre_ParVector *hy_x = hypre_AMSDataVertexCoordinateX(ams_data);
5532 hypre_ParVector *hy_y = hypre_AMSDataVertexCoordinateY(ams_data);
5533 hypre_ParVector *hy_z = hypre_AMSDataVertexCoordinateZ(ams_data);
5536 HYPRE_Int maxit = hypre_AMSDataMaxIter(ams_data);
5537 HYPRE_Real tol = hypre_AMSDataTol(ams_data);
5538 HYPRE_Int cycle_type = hypre_AMSDataCycleType(ams_data);
5539 HYPRE_Int ams_print_level = hypre_AMSDataPrintLevel(ams_data);
5542 HYPRE_Int A_relax_type = hypre_AMSDataARelaxType(ams_data);
5543 HYPRE_Int A_relax_times = hypre_AMSDataARelaxTimes(ams_data);
5544 HYPRE_Real A_relax_weight = hypre_AMSDataARelaxWeight(ams_data);
5545 HYPRE_Real A_omega = hypre_AMSDataAOmega(ams_data);
5546 HYPRE_Int A_cheby_order = hypre_AMSDataAChebyOrder(ams_data);
5547 HYPRE_Real A_cheby_fraction = hypre_AMSDataAChebyFraction(ams_data);
5549 HYPRE_Int B_Pi_coarsen_type = hypre_AMSDataPoissonAlphaAMGCoarsenType(ams_data);
5550 HYPRE_Int B_Pi_agg_levels = hypre_AMSDataPoissonAlphaAMGAggLevels(ams_data);
5551 HYPRE_Int B_Pi_relax_type = hypre_AMSDataPoissonAlphaAMGRelaxType(ams_data);
5552 HYPRE_Int B_Pi_coarse_relax_type = ams_data->B_Pi_coarse_relax_type;
5553 HYPRE_Real B_Pi_theta = hypre_AMSDataPoissonAlphaAMGStrengthThreshold(ams_data);
5554 HYPRE_Int B_Pi_interp_type = ams_data->B_Pi_interp_type;
5555 HYPRE_Int B_Pi_Pmax = ams_data->B_Pi_Pmax;
5557 HYPRE_Int B_G_coarsen_type = hypre_AMSDataPoissonBetaAMGCoarsenType(ams_data);
5558 HYPRE_Int B_G_agg_levels = hypre_AMSDataPoissonBetaAMGAggLevels(ams_data);
5559 HYPRE_Int B_G_relax_type = hypre_AMSDataPoissonBetaAMGRelaxType(ams_data);
5560 HYPRE_Int B_G_coarse_relax_type = ams_data->B_G_coarse_relax_type;
5561 HYPRE_Real B_G_theta = hypre_AMSDataPoissonBetaAMGStrengthThreshold(ams_data);
5562 HYPRE_Int B_G_interp_type = ams_data->B_G_interp_type;
5563 HYPRE_Int B_G_Pmax = ams_data->B_G_Pmax;
5565 HYPRE_AMSDestroy(ams);
5566 HYPRE_AMSCreate(&ams);
5567 ams_data = (hypre_AMSData *)ams;
5569 HYPRE_AMSSetDimension(ams,
dim);
5570 HYPRE_AMSSetTol(ams, tol);
5571 HYPRE_AMSSetMaxIter(ams, maxit);
5572 HYPRE_AMSSetCycleType(ams, cycle_type);
5573 HYPRE_AMSSetPrintLevel(ams, ams_print_level);
5575 HYPRE_AMSSetCoordinateVectors(ams, hy_x, hy_y, hy_z);
5577 HYPRE_AMSSetDiscreteGradient(ams, hy_G);
5578 HYPRE_AMSSetCoordinateVectors(ams, hy_x, hy_y, hy_z);
5579 HYPRE_AMSSetInterpolations(ams, hy_Pi, hy_Pix, hy_Piy, hy_Piz);
5580 ams_data->owns_Pi = owns_Pi;
5583 HYPRE_AMSSetSmoothingOptions(ams, A_relax_type, A_relax_times, A_relax_weight,
5586 hypre_AMSDataAChebyOrder(ams_data) = A_cheby_order;
5587 hypre_AMSDataAChebyFraction(ams_data) = A_cheby_fraction;
5589 HYPRE_AMSSetAlphaAMGOptions(ams, B_Pi_coarsen_type, B_Pi_agg_levels,
5591 B_Pi_theta, B_Pi_interp_type, B_Pi_Pmax);
5592 HYPRE_AMSSetBetaAMGOptions(ams, B_G_coarsen_type, B_G_agg_levels,
5594 B_G_theta, B_G_interp_type, B_G_Pmax);
5596 HYPRE_AMSSetAlphaAMGCoarseRelaxType(ams, B_Pi_coarse_relax_type);
5597 HYPRE_AMSSetBetaAMGCoarseRelaxType(ams, B_G_coarse_relax_type);
5599 ams_data->beta_is_zero = beta_is_zero;
5602 HYPRE_AMSDestroy(ams);
5604 MakeSolver(space_dim, ams_cycle_type);
5606 HYPRE_AMSSetPrintLevel(ams, print_level);
5607 if (singular) { HYPRE_AMSSetBetaPoissonMatrix(ams, NULL); }
5609 HYPRE_AMSSetDiscreteGradient(ams, *G);
5612 HYPRE_AMSSetCoordinateVectors(ams,
5613 x ? (HYPRE_ParVector)(*x) :
nullptr,
5614 y ? (HYPRE_ParVector)(*y) :
nullptr,
5615 z ? (HYPRE_ParVector)(*z) :
nullptr);
5619 HYPRE_AMSSetInterpolations(ams,
5620 Pi ? (HYPRE_ParCSRMatrix) *Pi :
nullptr,
5621 Pix ? (HYPRE_ParCSRMatrix) *Pix :
nullptr,
5622 Piy ? (HYPRE_ParCSRMatrix) *Piy :
nullptr,
5623 Piz ? (HYPRE_ParCSRMatrix) *Piz :
nullptr);
5631 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
5633 if (
A) { ResetAMSPrecond(); }
5650 HYPRE_AMSDestroy(ams);
5665 HYPRE_AMSSetPrintLevel(ams, print_lvl);
5666 print_level = print_lvl;
5684 x(x_), y(y_), z(z_),
5686 ND_Pi(NULL), ND_Pix(NULL), ND_Piy(NULL), ND_Piz(NULL),
5687 RT_Pi(NULL), RT_Pix(NULL), RT_Piy(NULL), RT_Piz(NULL)
5689 MFEM_ASSERT(C != NULL,
"");
5690 MFEM_ASSERT(G != NULL,
"");
5691 MFEM_ASSERT(x != NULL,
"");
5692 MFEM_ASSERT(y != NULL,
"");
5693 MFEM_ASSERT(z != NULL,
"");
5697 HYPRE_ADSSetCoordinateVectors(ads, *x, *y, *z);
5698 HYPRE_ADSSetDiscreteCurl(ads, *C);
5699 HYPRE_ADSSetDiscreteGradient(ads, *G);
5702 void HypreADS::MakeSolver()
5705 double rlx_weight = 1.0;
5706 double rlx_omega = 1.0;
5707 #if !defined(HYPRE_USING_GPU) 5709 int amg_coarsen_type = 10;
5710 int amg_agg_levels = 1;
5711 int amg_rlx_type = 8;
5712 double theta = 0.25;
5713 int amg_interp_type = 6;
5717 int amg_coarsen_type = 8;
5718 int amg_agg_levels = 0;
5719 int amg_rlx_type = 18;
5720 double theta = 0.25;
5721 int amg_interp_type = 6;
5725 HYPRE_ADSCreate(&ads);
5727 HYPRE_ADSSetTol(ads, 0.0);
5728 HYPRE_ADSSetMaxIter(ads, 1);
5729 HYPRE_ADSSetCycleType(ads, cycle_type);
5730 HYPRE_ADSSetPrintLevel(ads, 1);
5733 HYPRE_ADSSetSmoothingOptions(ads, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
5734 HYPRE_ADSSetAMGOptions(ads, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
5735 theta, amg_interp_type, amg_Pmax);
5736 HYPRE_ADSSetAMSOptions(ads, ams_cycle_type, amg_coarsen_type, amg_agg_levels,
5737 amg_rlx_type, theta, amg_interp_type, amg_Pmax);
5746 void HypreADS::MakeDiscreteMatrices(ParFiniteElementSpace *face_fespace)
5748 const FiniteElementCollection *face_fec = face_fespace->FEColl();
5750 (
dynamic_cast<const RT_Trace_FECollection*
>(face_fec) != NULL);
5752 if (face_fespace->GetNE() > 0)
5754 MFEM_VERIFY(!face_fespace->IsVariableOrder(),
"");
5757 p = face_fespace->GetFaceOrder(0) + 1;
5761 p = face_fespace->GetElementOrder(0);
5766 ParMesh *pmesh = (ParMesh *) face_fespace->GetMesh();
5767 FiniteElementCollection *vert_fec, *edge_fec;
5770 vert_fec =
new H1_Trace_FECollection(
p, 3);
5771 edge_fec =
new ND_Trace_FECollection(
p, 3);
5775 vert_fec =
new H1_FECollection(
p, 3);
5776 edge_fec =
new ND_FECollection(
p, 3);
5779 ParFiniteElementSpace *vert_fespace =
new ParFiniteElementSpace(pmesh,
5781 ParFiniteElementSpace *edge_fespace =
new ParFiniteElementSpace(pmesh,
5785 if (
p == 1 && pmesh->GetNodes() == NULL)
5787 ParGridFunction x_coord(vert_fespace);
5788 ParGridFunction y_coord(vert_fespace);
5789 ParGridFunction z_coord(vert_fespace);
5791 for (
int i = 0; i < pmesh->GetNV(); i++)
5793 coord = pmesh -> GetVertex(i);
5794 x_coord(i) = coord[0];
5795 y_coord(i) = coord[1];
5796 z_coord(i) = coord[2];
5798 x = x_coord.ParallelProject();
5799 y = y_coord.ParallelProject();
5800 z = z_coord.ParallelProject();
5804 HYPRE_ADSSetCoordinateVectors(ads, *x, *y, *z);
5814 ParDiscreteLinearOperator *curl;
5815 curl =
new ParDiscreteLinearOperator(edge_fespace, face_fespace);
5818 curl->AddTraceFaceInterpolator(
new CurlInterpolator);
5822 curl->AddDomainInterpolator(
new CurlInterpolator);
5826 C = curl->ParallelAssemble();
5828 HYPRE_ADSSetDiscreteCurl(ads, *C);
5832 ParDiscreteLinearOperator *grad;
5833 grad =
new ParDiscreteLinearOperator(vert_fespace, edge_fespace);
5836 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
5840 grad->AddDomainInterpolator(
new GradientInterpolator);
5844 G = grad->ParallelAssemble();
5847 HYPRE_ADSSetDiscreteGradient(ads, *G);
5851 RT_Pi = RT_Pix = RT_Piy = RT_Piz = NULL;
5852 ND_Pi = ND_Pix = ND_Piy = ND_Piz = NULL;
5853 if (
p > 1 || pmesh->GetNodes() != NULL)
5855 ParFiniteElementSpace *vert_fespace_d
5858 ParDiscreteLinearOperator *id_ND;
5859 id_ND =
new ParDiscreteLinearOperator(vert_fespace_d, edge_fespace);
5862 id_ND->AddTraceFaceInterpolator(
new IdentityInterpolator);
5866 id_ND->AddDomainInterpolator(
new IdentityInterpolator);
5871 if (ams_cycle_type < 10)
5873 ND_Pi = id_ND->ParallelAssemble();
5879 Array2D<HypreParMatrix *> ND_Pi_blocks;
5880 id_ND->GetParBlocks(ND_Pi_blocks);
5881 ND_Pix = ND_Pi_blocks(0,0);
5882 ND_Piy = ND_Pi_blocks(0,1);
5883 ND_Piz = ND_Pi_blocks(0,2);
5888 ParDiscreteLinearOperator *id_RT;
5889 id_RT =
new ParDiscreteLinearOperator(vert_fespace_d, face_fespace);
5892 id_RT->AddTraceFaceInterpolator(
new NormalInterpolator);
5896 id_RT->AddDomainInterpolator(
new IdentityInterpolator);
5901 if (cycle_type < 10)
5903 RT_Pi = id_RT->ParallelAssemble();
5908 Array2D<HypreParMatrix *> RT_Pi_blocks;
5909 id_RT->GetParBlocks(RT_Pi_blocks);
5910 RT_Pix = RT_Pi_blocks(0,0);
5911 RT_Piy = RT_Pi_blocks(0,1);
5912 RT_Piz = RT_Pi_blocks(0,2);
5917 HYPRE_ParCSRMatrix HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz;
5918 HY_RT_Pi = (RT_Pi) ? (HYPRE_ParCSRMatrix) *RT_Pi : NULL;
5919 HY_RT_Pix = (RT_Pix) ? (HYPRE_ParCSRMatrix) *RT_Pix : NULL;
5920 HY_RT_Piy = (RT_Piy) ? (HYPRE_ParCSRMatrix) *RT_Piy : NULL;
5921 HY_RT_Piz = (RT_Piz) ? (HYPRE_ParCSRMatrix) *RT_Piz : NULL;
5922 HYPRE_ParCSRMatrix HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz;
5923 HY_ND_Pi = (ND_Pi) ? (HYPRE_ParCSRMatrix) *ND_Pi : NULL;
5924 HY_ND_Pix = (ND_Pix) ? (HYPRE_ParCSRMatrix) *ND_Pix : NULL;
5925 HY_ND_Piy = (ND_Piy) ? (HYPRE_ParCSRMatrix) *ND_Piy : NULL;
5926 HY_ND_Piz = (ND_Piz) ? (HYPRE_ParCSRMatrix) *ND_Piz : NULL;
5927 HYPRE_ADSSetInterpolations(ads,
5928 HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz,
5929 HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz);
5931 delete vert_fespace_d;
5935 delete vert_fespace;
5937 delete edge_fespace;
5940 void HypreADS::Init(ParFiniteElementSpace *face_fespace)
5943 MakeDiscreteMatrices(face_fespace);
5946 void HypreADS::ResetADSPrecond()
5948 HYPRE_ADSDestroy(ads);
5952 HYPRE_ADSSetPrintLevel(ads, print_level);
5954 HYPRE_ADSSetDiscreteCurl(ads, *C);
5955 HYPRE_ADSSetDiscreteGradient(ads, *G);
5958 MFEM_VERIFY(x && y && z,
"");
5959 HYPRE_ADSSetCoordinateVectors(ads, *x, *y, *z);
5963 HYPRE_ParCSRMatrix HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz;
5964 HY_RT_Pi = (RT_Pi) ? (HYPRE_ParCSRMatrix) *RT_Pi : NULL;
5965 HY_RT_Pix = (RT_Pix) ? (HYPRE_ParCSRMatrix) *RT_Pix : NULL;
5966 HY_RT_Piy = (RT_Piy) ? (HYPRE_ParCSRMatrix) *RT_Piy : NULL;
5967 HY_RT_Piz = (RT_Piz) ? (HYPRE_ParCSRMatrix) *RT_Piz : NULL;
5968 HYPRE_ParCSRMatrix HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz;
5969 HY_ND_Pi = (ND_Pi) ? (HYPRE_ParCSRMatrix) *ND_Pi : NULL;
5970 HY_ND_Pix = (ND_Pix) ? (HYPRE_ParCSRMatrix) *ND_Pix : NULL;
5971 HY_ND_Piy = (ND_Piy) ? (HYPRE_ParCSRMatrix) *ND_Piy : NULL;
5972 HY_ND_Piz = (ND_Piz) ? (HYPRE_ParCSRMatrix) *ND_Piz : NULL;
5973 HYPRE_ADSSetInterpolations(ads,
5974 HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz,
5975 HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz);
5982 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
5984 if (
A) { ResetADSPrecond(); }
6001 HYPRE_ADSDestroy(ads);
6023 HYPRE_ADSSetPrintLevel(ads, print_lvl);
6024 print_level = print_lvl;
6027 HypreLOBPCG::HypreMultiVector::HypreMultiVector(
int n,
HypreParVector & v,
6028 mv_InterfaceInterpreter & interpreter)
6032 mv_ptr = mv_MultiVectorCreateFromSampleVector(&interpreter, nv,
6033 (HYPRE_ParVector)v);
6035 HYPRE_ParVector* vecs = NULL;
6037 mv_TempMultiVector* tmp =
6038 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
6039 vecs = (HYPRE_ParVector*)(tmp -> vector);
6042 hpv =
new HypreParVector*[nv];
6043 for (
int i=0; i<nv; i++)
6045 hpv[i] =
new HypreParVector(vecs[i]);
6049 HypreLOBPCG::HypreMultiVector::~HypreMultiVector()
6053 for (
int i=0; i<nv; i++)
6060 mv_MultiVectorDestroy(mv_ptr);
6064 HypreLOBPCG::HypreMultiVector::Randomize(HYPRE_Int seed_)
6066 mv_MultiVectorSetRandom(mv_ptr, seed_);
6070 HypreLOBPCG::HypreMultiVector::GetVector(
unsigned int i)
6072 MFEM_ASSERT((
int)i < nv,
"index out of range");
6078 HypreLOBPCG::HypreMultiVector::StealVectors()
6080 HypreParVector ** hpv_ret = hpv;
6084 mv_TempMultiVector * mv_tmp =
6085 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
6087 mv_tmp->ownsVectors = 0;
6089 for (
int i=0; i<nv; i++)
6091 hpv_ret[i]->SetOwnership(1);
6109 MPI_Comm_size(comm,&numProcs);
6110 MPI_Comm_rank(comm,&myid);
6112 HYPRE_ParCSRSetupInterpreter(&interpreter);
6113 HYPRE_ParCSRSetupMatvec(&matvec_fn);
6114 HYPRE_LOBPCGCreate(&interpreter, &matvec_fn, &lobpcg_solver);
6123 HYPRE_LOBPCGDestroy(lobpcg_solver);
6129 HYPRE_LOBPCGSetTol(lobpcg_solver, tol);
6135 #if MFEM_HYPRE_VERSION >= 21101 6136 HYPRE_LOBPCGSetRTol(lobpcg_solver, rel_tol);
6138 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
6145 HYPRE_LOBPCGSetMaxIter(lobpcg_solver, max_iter);
6153 HYPRE_LOBPCGSetPrintLevel(lobpcg_solver, logging);
6160 HYPRE_LOBPCGSetPrecondUsageMode(lobpcg_solver, pcg_mode);
6166 HYPRE_LOBPCGSetPrecond(lobpcg_solver,
6167 (HYPRE_PtrToSolverFcn)this->PrecondSolve,
6168 (HYPRE_PtrToSolverFcn)this->PrecondSetup,
6169 (HYPRE_Solver)&precond);
6177 if (HYPRE_AssumedPartitionCheck())
6181 MPI_Scan(&locSize, &part[1], 1, HYPRE_MPI_BIG_INT, MPI_SUM, comm);
6183 part[0] = part[1] - locSize;
6185 MPI_Allreduce(&locSize, &glbSize, 1, HYPRE_MPI_BIG_INT, MPI_SUM, comm);
6191 MPI_Allgather(&locSize, 1, HYPRE_MPI_BIG_INT,
6192 &part[1], 1, HYPRE_MPI_BIG_INT, comm);
6195 for (
int i=0; i<numProcs; i++)
6197 part[i+1] += part[i];
6200 glbSize = part[numProcs];
6209 const bool is_device_ptr =
true;
6212 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
6213 matvec_fn.Matvec = this->OperatorMatvec;
6214 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
6216 HYPRE_LOBPCGSetup(lobpcg_solver,(HYPRE_Matrix)&A,NULL,NULL);
6222 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
6223 matvec_fn.Matvec = this->OperatorMatvec;
6224 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
6226 HYPRE_LOBPCGSetupB(lobpcg_solver,(HYPRE_Matrix)&M,NULL);
6235 for (
int i=0; i<nev; i++)
6237 eigs[i] = eigenvalues[i];
6244 return multi_vec->GetVector(i);
6251 if ( multi_vec == NULL )
6253 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::SetInitialVectors()");
6255 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
6259 for (
int i=0; i < min(num_vecs,nev); i++)
6261 multi_vec->GetVector(i) = *vecs[i];
6265 for (
int i=min(num_vecs,nev); i < nev; i++)
6267 multi_vec->GetVector(i).Randomize(seed);
6271 if ( subSpaceProj != NULL )
6274 y = multi_vec->GetVector(0);
6276 for (
int i=1; i<nev; i++)
6278 subSpaceProj->
Mult(multi_vec->GetVector(i),
6279 multi_vec->GetVector(i-1));
6281 subSpaceProj->
Mult(y,
6282 multi_vec->GetVector(nev-1));
6290 if ( multi_vec == NULL )
6292 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::Solve()");
6294 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
6295 multi_vec->Randomize(seed);
6297 if ( subSpaceProj != NULL )
6300 y = multi_vec->GetVector(0);
6302 for (
int i=1; i<nev; i++)
6304 subSpaceProj->
Mult(multi_vec->GetVector(i),
6305 multi_vec->GetVector(i-1));
6307 subSpaceProj->
Mult(y, multi_vec->GetVector(nev-1));
6318 HYPRE_LOBPCGSolve(lobpcg_solver, NULL, *multi_vec, eigenvalues);
6322 HypreLOBPCG::OperatorMatvecCreate(
void *A,
6329 return ( matvec_data );
6333 HypreLOBPCG::OperatorMatvec(
void *matvec_data,
6334 HYPRE_Complex
alpha,
6340 MFEM_VERIFY(
alpha == 1.0 && beta == 0.0,
"values not supported");
6342 Operator *Aop = (Operator*)A;
6344 hypre_ParVector * xPar = (hypre_ParVector *)x;
6345 hypre_ParVector * yPar = (hypre_ParVector *)y;
6347 HypreParVector xVec(xPar);
6348 HypreParVector yVec(yPar);
6350 Aop->Mult( xVec, yVec );
6354 yVec.HypreReadWrite();
6360 HypreLOBPCG::OperatorMatvecDestroy(
void *matvec_data )
6366 HypreLOBPCG::PrecondSolve(
void *solver,
6371 Solver *
PC = (Solver*)solver;
6373 hypre_ParVector * bPar = (hypre_ParVector *)
b;
6374 hypre_ParVector * xPar = (hypre_ParVector *)x;
6376 HypreParVector bVec(bPar);
6377 HypreParVector xVec(xPar);
6379 PC->Mult( bVec, xVec );
6383 xVec.HypreReadWrite();
6389 HypreLOBPCG::PrecondSetup(
void *solver,
6407 MPI_Comm_size(comm,&numProcs);
6408 MPI_Comm_rank(comm,&myid);
6410 HYPRE_AMECreate(&ame_solver);
6411 HYPRE_AMESetPrintLevel(ame_solver, 0);
6418 mfem_hypre_TFree_host(multi_vec);
6423 for (
int i=0; i<nev; i++)
6425 delete eigenvectors[i];
6428 delete [] eigenvectors;
6432 mfem_hypre_TFree_host(eigenvalues);
6435 HYPRE_AMEDestroy(ame_solver);
6443 HYPRE_AMESetBlockSize(ame_solver, nev);
6449 HYPRE_AMESetTol(ame_solver, tol);
6455 #if MFEM_HYPRE_VERSION >= 21101 6456 HYPRE_AMESetRTol(ame_solver, rel_tol);
6458 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
6465 HYPRE_AMESetMaxIter(ame_solver, max_iter);
6473 HYPRE_AMESetPrintLevel(ame_solver, logging);
6480 ams_precond = &precond;
6488 HYPRE_Solver ams_precond_ptr = (HYPRE_Solver)*ams_precond;
6490 ams_precond->
SetupFcn()(*ams_precond,A,NULL,NULL);
6492 HYPRE_AMESetAMSSolver(ame_solver, ams_precond_ptr);
6495 HYPRE_AMESetup(ame_solver);
6501 HYPRE_ParCSRMatrix parcsr_M = M;
6502 HYPRE_AMESetMassMatrix(ame_solver,(HYPRE_ParCSRMatrix)parcsr_M);
6508 HYPRE_AMESolve(ame_solver);
6511 HYPRE_AMEGetEigenvalues(ame_solver,&eigenvalues);
6514 HYPRE_AMEGetEigenvectors(ame_solver,&multi_vec);
6521 eigs.
SetSize(nev); eigs = -1.0;
6524 for (
int i=0; i<nev; i++)
6526 eigs[i] = eigenvalues[i];
6531 HypreAME::createDummyVectors()
const 6534 for (
int i=0; i<nev; i++)
6541 const HypreParVector &
6544 if ( eigenvectors == NULL )
6546 this->createDummyVectors();
6549 return *eigenvectors[i];
6555 if ( eigenvectors == NULL )
6557 this->createDummyVectors();
6562 eigenvectors = NULL;
MemoryType GetHypreMemoryType()
The MemoryType used by MFEM when allocating arrays for Hypre objects.
virtual ~HypreBoomerAMG()
void SetAbsTol(double atol)
void GetEigenvalues(Array< double > &eigenvalues) const
Collect the converged eigenvalues.
Hash function for data sequences.
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
void SetType(HYPRE_Int ilu_type)
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's GMRES.
void EliminateRowsCols(const Array< int > &rows_cols, const HypreParVector &X, HypreParVector &B)
HypreADS(ParFiniteElementSpace *face_fespace)
HypreParMatrix * ExtractSubmatrix(const Array< int > &indices, double threshold=0.0) const
const T * Read(MemoryClass mc, int size) const
Get read-only access to the memory with the given MemoryClass.
virtual int NumNonZeroElems() const
Returns the number of the nonzero elements in the matrix.
static constexpr Type default_type
HypreEuclid(MPI_Comm comm)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void EliminateBC(const HypreParMatrix &A, const HypreParMatrix &Ae, const Array< int > &ess_dof_list, const Vector &X, Vector &B)
Eliminate essential BC specified by ess_dof_list from the solution X to the r.h.s. B.
HypreParVector * NewTrueDofVector()
HypreParVector * X0
FIR Filter Temporary Vectors.
void Clear()
Clear the contents of the SparseMatrix.
double min_eig_est
Minimal eigenvalue estimate for polynomial smoothing.
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
static MemoryClass GetHostMemoryClass()
Get the current Host MemoryClass. This is the MemoryClass used by most MFEM host Memory objects...
void SetPrintLevel(int print_lvl)
void SetRowScale(int row_scale)
void SetMassMatrix(const HypreParMatrix &M)
void WrapMemoryWrite(Memory< double > &mem)
Replace the HypreParVector's data with the given Memory, mem, and prepare the vector for write access...
int setup_called
Was hypre's Setup function called already?
void SetLogging(int logging)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
const HypreParVector & GetEigenvector(unsigned int i) const
Extract a single eigenvector.
void MakeRef(const HypreParMatrix &master)
Make this HypreParMatrix a reference to 'master'.
void Read_IJMatrix(MPI_Comm comm, const char *fname)
Read a matrix saved as a HYPRE_IJMatrix.
bool CanShallowCopy(const Memory< T > &src, MemoryClass mc)
Return true if the src Memory can be used with the MemoryClass mc.
void SetSize(int s)
Resize the vector to size s.
HypreParMatrix & Add(const double beta, const HypreParMatrix &B)
HypreParVector * B
Right-hand side and solution vector.
void Delete()
Delete the owned pointers and reset the Memory object.
double window_params[3]
Parameters for windowing function of FIR filter.
virtual const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's PCG.
MemoryType GetHostMemoryType() const
Return the host MemoryType of the Memory object.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void GetEigenvalues(Array< double > &eigenvalues) const
Collect the converged eigenvalues.
void SetInitialVectors(int num_vecs, HypreParVector **vecs)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void SetWindowByName(const char *window_name)
Convenience function for setting canonical windowing parameters.
Biwise-OR of all HIP backends.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
T * GetData()
Returns the data.
Issue warnings on hypre errors.
int Size() const
Returns the size of the vector.
T * Write(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for write access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true...
std::string GetHash() const
Return the hash string for the current sequence and reset (clear) the sequence.
void SetPreconditioner(HypreSolver &precond)
virtual double * HostWrite()
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
HypreILU()
Constructor; sets the default options.
int GetNumCols() const
Returns the number of columns in the diagonal block of the ParCSRMatrix.
T * Write(MemoryClass mc, int size)
Get write-only access to the memory with the given MemoryClass.
HypreAMS(ParFiniteElementSpace *edge_fespace)
Construct the AMS solver on the given edge finite element space.
int NumRows() const
Get the number of rows (size of output) of the Operator. Synonym with Height().
void SetPrintLevel(int print_lvl)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void SetPreconditioner(Solver &precond)
void ResetTranspose() const
Reset (destroy) the internal transpose matrix that is created by EnsureMultTranspose() and MultTransp...
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
Memory< HYPRE_Int > & GetDiagMemoryJ()
void SetMassMatrix(Operator &M)
Abstract parallel finite element space.
HypreParVector()
Default constructor, no underlying hypre_ParVector is created.
void SetPrintLevel(int logging)
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
void CopyFrom(const Memory &src, int size)
Copy size entries from src to *this.
void HostRead() const
Update the internal hypre_ParCSRMatrix object, A, to be on host.
void SetAdvectiveOptions(int distance=15, const std::string &prerelax="", const std::string &postrelax="FFC")
HYPRE_BigInt N() const
Returns the global number of columns.
void BlockInverseScale(const HypreParMatrix *A, HypreParMatrix *C, const Vector *b, HypreParVector *d, int blocksize, BlockInverseScaleJob job)
void HostWrite()
Update the internal hypre_ParCSRMatrix object, A, to be on host.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Relax the linear system Ax=b.
bool pos_l1_norms
If set, take absolute values of the computed l1_norms.
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B, bool own_matrix)
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve the linear system Ax=b.
void SetPrintLevel(int print_lvl)
void ScaleRows(const Vector &s)
Scale the local row i by s(i).
void SetParams(double threshold, int max_levels)
double poly_fraction
Fraction of spectrum to smooth for polynomial relaxation.
Memory< double > & GetMemoryData()
Memory< double > & GetMemory()
Return a reference to the Memory object used by the Vector.
void SetPrintLevel(int print_lvl)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Memory< int > & GetMemoryI()
int poly_scale
Apply the polynomial smoother to A or D^{-1/2} A D^{-1/2}.
void MergeDiagAndOffd(SparseMatrix &merged)
Get a single SparseMatrix containing all rows from this processor, merged from the diagonal and off-d...
HashFunction & AppendDoubles(const double *doubles, size_t num_doubles)
Add a sequence of doubles for hashing, given as a c-array.
void SetMaxIter(HYPRE_Int max_iter)
HypreFGMRES(MPI_Comm comm)
Memory< int > & GetMemoryJ()
void SetWindowParameters(double a, double b, double c)
Set parameters for windowing function for FIR smoother.
void SetLoadBal(double loadbal)
HypreGMRES(MPI_Comm comm)
Vector & operator=(const double *v)
Copy Size() entries from v.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
bool MemoryClassContainsType(MemoryClass mc, MemoryType mt)
Return true iff the MemoryType mt is contained in the MemoryClass mc.
HypreLOBPCG(MPI_Comm comm)
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
void EliminateBC(const HypreParMatrix &Ae, const Array< int > &ess_dof_list, const Vector &X, Vector &B) const
Eliminate essential BC specified by ess_dof_list from the solution X to the r.h.s. B.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void SetSymmetry(int sym)
void HypreStealOwnership(HypreParMatrix &A_hyp, SparseMatrix &A_diag)
Make A_hyp steal ownership of its diagonal part A_diag.
virtual ~HypreParaSails()
double f(const Vector &xvec)
void SetDevicePtrOwner(bool own) const
Set/clear the ownership flag for the device pointer. Ownership indicates whether the pointer will be ...
void SetMaxIter(int max_iter)
bool Empty() const
Return true if the Memory object is empty, see Reset().
double * l1_norms
l1 norms of the rows of A
void SetOwnerFlags(signed char diag, signed char offd, signed char colmap)
Explicitly set the three ownership flags, see docs for diagOwner etc.
virtual void Setup(const HypreParVector &b, HypreParVector &x) const
Set up the solver (if not set up already, also called automatically by HypreSolver::Mult).
void SetLogging(int logging)
virtual HYPRE_PtrToParSolverFcn SolveFcn() const =0
hypre's internal Solve function
virtual double * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
void SetRelTol(double rel_tol)
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
void SetResidualConvergenceOptions(int res_frequency=-1, double rtol=0.0)
int to_int(const std::string &str)
Convert a string to an int.
Abort on hypre errors (default in base class)
void SetLogging(int logging)
void Print(const char *fname, HYPRE_Int offi=0, HYPRE_Int offj=0) const
Prints the locally owned rows in parallel.
ParMesh * GetParMesh() const
HypreParaSails(MPI_Comm comm)
void HypreWrite()
Prepare the HypreParVector for write access in hypre's device memory space, HYPRE_MEMORY_DEVICE.
void WrapHypreParVector(hypre_ParVector *y, bool owner=true)
Converts hypre's format to HypreParVector.
void AbsMultTranspose(double a, const Vector &x, double b, Vector &y) const
Computes y = a * |At| * x + b * y, using entry-wise absolute values of the transpose of the matrix A...
bool WrapVectors(const Vector &b, Vector &x) const
Makes the internal HypreParVectors B and X wrap the input vectors b and x.
void Read(MPI_Comm comm, const char *fname)
Reads a HypreParVector from files saved with HypreParVector::Print.
HypreParMatrix * LeftDiagMult(const SparseMatrix &D, HYPRE_BigInt *row_starts=NULL) const
Multiply the HypreParMatrix on the left by a block-diagonal parallel matrix D and return the result a...
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
HypreParVector ** StealEigenvectors()
Transfer ownership of the converged eigenvectors.
const HypreParMatrix * A
The linear system matrix.
HYPRE_Int Randomize(HYPRE_Int seed)
Set random values.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's FGMRES.
virtual void MultTranspose(const Vector &b, Vector &x) const
Apply transpose of the smoother to relax the linear system Ax=b.
Ignore hypre errors (see e.g. HypreADS)
double relax_weight
Damping coefficient (usually <= 1)
HYPRE_BigInt * GetColStarts() const
Return the parallel column partitioning array.
void SetElasticityOptions(ParFiniteElementSpace *fespace)
void Sort()
Sorts the array in ascending order. This requires operator< to be defined for T.
int Capacity() const
Return the size of the allocated memory.
void GetDiag(Vector &diag) const
Get the local diagonal of the matrix.
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true...
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
void SetLevelOfFill(HYPRE_Int lev_fill)
Set the fill level for ILU(k); the default is k=1.
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
HypreParMatrix * A
The linear system matrix.
HYPRE_BigInt GlobalTrueVSize() const
Biwise-OR of all CUDA backends.
Dynamic 2D array using row-major layout.
virtual void SetOperator(const Operator &op)
virtual HYPRE_PtrToParSolverFcn SetupFcn() const =0
hypre's internal Setup function
void SetLogging(int logging)
HypreParMatrix()
An empty matrix to be used as a reference to an existing matrix.
bool A_is_symmetric
A flag that indicates whether the linear system matrix A is symmetric.
void EnsureMultTranspose() const
Ensure the action of the transpose is performed fast.
void SetMaxIter(int max_iter)
int ParCSRRelax_FIR(hypre_ParCSRMatrix *A, hypre_ParVector *f, double max_eig, int poly_order, double *fir_coeffs, hypre_ParVector *u, hypre_ParVector *x0, hypre_ParVector *x1, hypre_ParVector *x2, hypre_ParVector *x3)
void SetMaxIter(int max_iter)
void SetPolyOptions(int poly_order, double poly_fraction, int eig_est_cg_iter=10)
Set parameters for polynomial smoothing.
void SetSOROptions(double relax_weight, double omega)
Set SOR-related parameters.
MPI_Comm GetComm() const
MPI communicator.
T * HostWrite(Memory< T > &mem, int size)
Shortcut to Write(const Memory<T> &mem, int size, false)
void CopyMemory(Memory< T > &src, Memory< T > &dst, MemoryClass dst_mc, bool dst_owner)
Shallow or deep copy src to dst with the goal to make the array src accessible through dst with the M...
Wrapper for hypre's parallel vector class.
HypreParMatrix * EliminateCols(const Array< int > &cols)
int ParCSRRelax_Taubin(hypre_ParCSRMatrix *A, hypre_ParVector *f, double lambda, double mu, int N, double max_eig, hypre_ParVector *u, hypre_ParVector *r)
double p(const Vector &x, double t)
static MemoryType GetHostMemoryType()
Get the current Host MemoryType. This is the MemoryType used by most MFEM classes when allocating mem...
void PrintHash(std::ostream &out) const
Print sizes and hashes for all data arrays of the HypreParMatrix from the local MPI rank...
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
MemoryType
Memory types supported by MFEM.
void HypreRead() const
Prepare the HypreParVector for read access in hypre's device memory space, HYPRE_MEMORY_DEVICE.
void SetPrintLevel(int print_lvl)
void PrintCommPkg(std::ostream &out=mfem::out) const
Print information about the hypre_ParCSRCommPkg of the HypreParMatrix.
signed char OwnsColMap() const
Get colmap ownership flag.
void SetHostPtrOwner(bool own) const
Set/clear the ownership flag for the host pointer. Ownership indicates whether the pointer will be de...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void Solve()
Solve the eigenproblem.
void SetData(double *data_)
Sets the data of the Vector and the hypre_ParVector to data_.
void SetNumModes(int num_eigs)
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
HypreParMatrix * ParAdd(const HypreParMatrix *A, const HypreParMatrix *B)
Returns the matrix A + B.
double max_eig_est
Maximal eigenvalue estimate for polynomial smoothing.
static bool Allows(unsigned long b_mask)
Return true if any of the backends in the backend mask, b_mask, are allowed.
int NumCols() const
Get the number of columns (size of input) of the Operator. Synonym with Width().
A class to initialize the size of a Tensor.
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
void SetRelTol(double rel_tol)
HashFunction & AppendInts(const int_type *ints, size_t num_ints)
Add a sequence of integers for hashing, given as a c-array.
double Norml1() const
Returns the l_1 norm of the vector.
void MakeAlias(const Memory &base, int offset, int size)
Create a memory object that points inside the memory object base.
HypreParMatrix * Transpose() const
Returns the transpose of *this.
void GetBlocks(Array2D< HypreParMatrix *> &blocks, bool interleaved_rows=false, bool interleaved_cols=false) const
int height
Dimension of the output / number of rows in the matrix.
void SetMaxIter(int max_iter)
void SetFIRCoefficients(double max_eig)
Compute window and Chebyshev coefficients for given polynomial order.
void EliminateRows(const Array< int > &rows)
Eliminate rows from the diagonal and off-diagonal blocks of the matrix.
double * fir_coeffs
Combined coefficients for windowing and Chebyshev polynomials.
void MakeDataOwner() const
Set the Vector data (host pointer) ownership flag.
void Threshold(double threshold=0.0)
Remove values smaller in absolute value than some threshold.
const T * HostRead(const Memory< T > &mem, int size)
Shortcut to Read(const Memory<T> &mem, int size, false)
double InnerProduct(HypreParVector *x, HypreParVector *y)
void SetPrintLevel(HYPRE_Int print_level)
Set the print level: 0 = none, 1 = setup, 2 = solve, 3 = setup+solve.
Host memory; using new[] and delete[].
constexpr MemoryClass GetHypreMemoryClass()
The MemoryClass used by Hypre objects.
void Print(const char *fname) const
Prints the locally owned rows in parallel.
void HypreReadWrite()
Prepare the HypreParVector for read and write access in hypre's device memory space, HYPRE_MEMORY_DEVICE.
Memory< HYPRE_Int > & GetDiagMemoryI()
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
void InvScaleRows(const Vector &s)
Scale the local row i by 1./s(i)
int Size() const
Returns the number of TYPE I elements.
void SetTaubinOptions(double lambda, double mu, int iter)
Set parameters for Taubin's lambda-mu method.
HypreParVector * B
Right-hand side and solution vectors.
MemoryType GetDeviceMemoryType() const
Return the device MemoryType of the Memory object. If the device MemoryType is not set...
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
A simple singleton class for hypre's global settings, that 1) calls HYPRE_Init() and sets some GPU-re...
void ClearOwnerFlags() const
Clear the ownership flags for the host and device pointers, as well as any internal data allocated by...
T * ReadWrite(MemoryClass mc, int size)
Get read-write access to the memory with the given MemoryClass.
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
MemoryType GetMemoryType(MemoryClass mc)
Return a suitable MemoryType for a given MemoryClass.
void SetOperator(Operator &A)
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
void Destroy()
Destroy a vector.
void SetLocalReordering(HYPRE_Int reorder_type)
void HypreRead() const
Update the internal hypre_ParCSRMatrix object, A, to be in hypre memory space.
int relax_times
Number of relaxation sweeps.
Class used by MFEM to store pointers to host and/or device memory.
void operator*=(double s)
Scale all entries by s: A_scaled = s*A.
void SetPrintLevel(int logging)
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
double ParNormlp(const Vector &vec, double p, MPI_Comm comm)
Compute the l_p norm of the Vector which is split without overlap across the given communicator...
int eig_est_cg_iter
Number of CG iterations to determine eigenvalue estimates.
void SetOwnership(int own)
Sets ownership of the internal hypre_ParVector.
double Norml2() const
Returns the l2 norm of the vector.
Abstract class for hypre's solvers and preconditioners.
int Size_of_connections() const
ErrorMode error_mode
How to treat hypre errors.
void AbsMult(double a, const Vector &x, double b, Vector &y) const
Computes y = a * |A| * x + b * y, using entry-wise absolute values of the matrix A.
bool OwnsHostPtr() const
Return true if the host pointer is owned. Ownership indicates whether the pointer will be deleted by ...
int Size() const
Return the logical size of the array.
HypreParVector & operator=(double d)
Set constant values.
void SetAbsTol(double tol)
void delete_hypre_ParCSRMatrixColMapOffd(hypre_ParCSRMatrix *A)
void CopyConvertMemory(Memory< SrcT > &src, MemoryClass dst_mc, Memory< DstT > &dst)
Deep copy and convert src to dst with the goal to make the array src accessible through dst with the ...
hypre_ParCSRMatrix * StealData()
Changes the ownership of the matrix.
void SetPrecondUsageMode(int pcg_mode)
void SetOperator(const HypreParMatrix &A)
void SetSystemsOptions(int dim, bool order_bynodes=false)
void SetFilter(double filter)
void DropSmallEntries(double tol)
Wrapper for hypre_ParCSRMatrixDropSmallEntries in different versions of hypre. Drop off-diagonal entr...
void SetMaxIter(int max_iter)
HYPRE_BigInt GetGlobalNumCols() const
Return the global number of columns.
Vector * GlobalVector() const
Returns the global vector in each processor.
void GetOffd(SparseMatrix &offd, HYPRE_BigInt *&cmap) const
Get the local off-diagonal block. NOTE: 'offd' will not own any data.
double omega
SOR parameter (usually in (0,2))
HYPRE_BigInt M() const
Returns the global number of rows.
signed char OwnsOffd() const
Get offd ownership flag.
double u(const Vector &xvec)
HYPRE_Int MultTranspose(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0) const
Computes y = alpha * A^t * x + beta * y.
void WrapHypreParCSRMatrix(hypre_ParCSRMatrix *a, bool owner=true)
Converts hypre's format to HypreParMatrix.
Wrapper for hypre's ParCSR matrix class.
void HostReadWrite()
Update the internal hypre_ParCSRMatrix object, A, to be on host.
Memory< double > auxB
Auxiliary buffers for the case when the input or output arrays in methods like Mult(const Vector &...
void Swap(SparseMatrix &other)
~HypreParVector()
Calls hypre's destroy function.
HypreParMatrix * HypreParMatrixFromBlocks(Array2D< HypreParMatrix *> &blocks, Array2D< double > *blockCoeff)
Returns a merged hypre matrix constructed from hypre matrix blocks.
Memory< double > & GetDiagMemoryData()
void Solve()
Solve the eigenproblem.
HYPRE_BigInt * GetTrueDofOffsets() const
HypreParVector * V
Temporary vectors.
double Normlinf() const
Returns the l_infinity norm of the vector.
void SetType(HypreSmoother::Type type, int relax_times=1)
Set the relaxation type and number of sweeps.
void GatherBlockOffsetData(MPI_Comm comm, const int rank, const int nprocs, const int num_loc, const Array< int > &offsets, std::vector< int > &all_num_loc, const int numBlocks, std::vector< std::vector< HYPRE_BigInt >> &blockProcOffsets, std::vector< HYPRE_BigInt > &procOffsets, std::vector< std::vector< int >> &procBlockOffsets, HYPRE_BigInt &firstLocal, HYPRE_BigInt &globalNum)
virtual double * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
MemoryClass
Memory classes identify sets of memory types.
HYPRE_BigInt GetGlobalNumRows() const
Return the global number of rows.
void WrapMemoryReadWrite(Memory< double > &mem)
Replace the HypreParVector's data with the given Memory, mem, and prepare the vector for read and wri...
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0) const
Computes y = alpha * A * x + beta * y.
int width
Dimension of the input / number of columns in the matrix.
HypreParVector CreateCompatibleVector() const
Constructs a HypreParVector compatible with the calling vector.
int poly_order
Order of the smoothing polynomial.
void SetTol(HYPRE_Real tol)
int GetNumRows() const
Returns the number of rows in the diagonal block of the ParCSRMatrix.
double lambda
Taubin's lambda-mu method parameters.
void WrapMemoryRead(const Memory< double > &mem)
Replace the HypreParVector's data with the given Memory, mem, and prepare the vector for read access ...
const HypreParVector & GetEigenvector(unsigned int i) const
Extract a single eigenvector.
double sigma(const Vector &x)
void HypreReadWrite()
Update the internal hypre_ParCSRMatrix object, A, to be in hypre memory space.
HYPRE_BigInt * GetRowStarts() const
Return the parallel row partitioning array.