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);
283 if (size != y.
Size())
307 hypre_VectorData(hypre_ParVectorLocalVector(x)) = data_;
313 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
314 hypre_VectorData(x_loc) =
316 #ifdef HYPRE_USING_GPU
317 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
323 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
325 #ifdef HYPRE_USING_GPU
326 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
332 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
334 #ifdef HYPRE_USING_GPU
335 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
345 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
346 hypre_VectorData(x_loc) =
348 #ifdef HYPRE_USING_GPU
349 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
360 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
362 #ifdef HYPRE_USING_GPU
363 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
374 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
376 #ifdef HYPRE_USING_GPU
377 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
384 return hypre_ParVectorSetRandomValues(x,seed);
389 hypre_ParVectorPrint(x,fname);
396 hypre_ParVectorDestroy(x);
399 x = hypre_ParVectorRead(comm, fname);
400 own_ParVector =
true;
408 hypre_ParVectorDestroy(x);
415 return hypre_ParVectorInnerProd(*x, *y);
420 return hypre_ParVectorInnerProd(x, y);
429 double loc_norm = vec.
Norml1();
430 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
434 double loc_norm = vec*vec;
435 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
441 for (
int i = 0; i < vec.
Size(); i++)
443 sum += pow(fabs(vec(i)), p);
445 MPI_Allreduce(&sum, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
446 norm = pow(norm, 1.0/p);
451 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_MAX, comm);
473 template <
typename T>
508 template <
typename SrcT,
typename DstT>
516 MFEM_FORALL(i, capacity, dst_p[i] = src_p[i];);
520 void HypreParMatrix::Init()
525 diagOwner = offdOwner = colMapOwner = -1;
537 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
538 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
539 const int num_rows =
NumRows();
542 diag->i =
const_cast<HYPRE_Int*
>(mem_diag.
I.
Read(mc, num_rows+1));
543 diag->j =
const_cast<HYPRE_Int*
>(mem_diag.
J.
Read(mc, diag_nnz));
544 diag->data =
const_cast<double*
>(mem_diag.
data.
Read(mc, diag_nnz));
545 offd->i =
const_cast<HYPRE_Int*
>(mem_offd.
I.
Read(mc, num_rows+1));
546 offd->j =
const_cast<HYPRE_Int*
>(mem_offd.
J.
Read(mc, offd_nnz));
547 offd->data =
const_cast<double*
>(mem_offd.
data.
Read(mc, offd_nnz));
548 #if MFEM_HYPRE_VERSION >= 21800
549 decltype(diag->memory_location) ml =
551 diag->memory_location = ml;
552 offd->memory_location = ml;
558 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
559 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
560 const int num_rows =
NumRows();
563 diag->i = mem_diag.
I.
ReadWrite(mc, num_rows+1);
566 offd->i = mem_offd.
I.
ReadWrite(mc, num_rows+1);
569 #if MFEM_HYPRE_VERSION >= 21800
570 decltype(diag->memory_location) ml =
572 diag->memory_location = ml;
573 offd->memory_location = ml;
577 void HypreParMatrix::Write(
MemoryClass mc,
bool set_diag,
bool set_offd)
579 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
580 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
593 #if MFEM_HYPRE_VERSION >= 21800
594 decltype(diag->memory_location) ml =
596 if (set_diag) { diag->memory_location = ml; }
597 if (set_offd) { offd->memory_location = ml; }
615 #if MFEM_HYPRE_VERSION >= 21800
616 MemoryType diag_mt = (A->diag->memory_location == HYPRE_MEMORY_HOST
618 MemoryType offd_mt = (A->offd->memory_location == HYPRE_MEMORY_HOST
624 diagOwner = HypreCsrToMem(A->diag, diag_mt,
false, mem_diag);
625 offdOwner = HypreCsrToMem(A->offd, offd_mt,
false, mem_offd);
631 hypre_CSRMatrix *hypre_csr,
646 const int num_rows = csr->
Height();
648 hypre_csr->i =
const_cast<HYPRE_Int*
>(mem_csr.
I.
Read(hypre_mc, num_rows+1));
649 hypre_csr->j =
const_cast<HYPRE_Int*
>(mem_csr.
J.
Read(hypre_mc, nnz));
650 hypre_csr->data =
const_cast<double*
>(mem_csr.
data.
Read(hypre_mc, nnz));
653 "invalid state: host ownership for I and J differ!");
658 signed char HypreParMatrix::CopyBoolCSR(Table *bool_csr,
659 MemoryIJData &mem_csr,
660 hypre_CSRMatrix *hypre_csr)
665 CopyMemory(bool_csr->GetIMemory(), mem_csr.I, hypre_mc,
false);
666 CopyMemory(bool_csr->GetJMemory(), mem_csr.J, hypre_mc,
false);
672 const int num_rows = bool_csr->Size();
673 const int nnz = bool_csr->Size_of_connections();
676 for (
int i = 0; i < nnz; i++)
680 hypre_csr->i =
const_cast<HYPRE_Int*
>(mem_csr.I.Read(hypre_mc, num_rows+1));
681 hypre_csr->j =
const_cast<HYPRE_Int*
>(mem_csr.J.Read(hypre_mc, nnz));
682 hypre_csr->data =
const_cast<double*
>(mem_csr.data.Read(hypre_mc, nnz));
684 MFEM_ASSERT(mem_csr.I.OwnsHostPtr() == mem_csr.J.OwnsHostPtr(),
685 "invalid state: host ownership for I and J differ!");
686 return (mem_csr.I.OwnsHostPtr() ? 1 : 0) +
687 (mem_csr.data.OwnsHostPtr() ? 2 : 0);
693 static void CopyCSR_J(
const int nnz,
const MemoryIJData &mem_csr,
699 MFEM_FORALL(i, nnz, dst_p[i] = src_p[i];);
704 signed char HypreParMatrix::HypreCsrToMem(hypre_CSRMatrix *h_mat,
711 mem.I.Wrap(h_mat->i, nr1, h_mat_mt, own_ija);
712 mem.J.Wrap(h_mat->j, nnz, h_mat_mt, own_ija);
713 mem.data.Wrap(h_mat->data, nnz, h_mat_mt, own_ija);
719 h_mem.I.New(nr1, hypre_mt);
720 h_mem.I.CopyFrom(mem.I, nr1);
722 h_mem.J.New(nnz, hypre_mt);
723 h_mem.J.CopyFrom(mem.J, nnz);
725 h_mem.data.New(nnz, hypre_mt);
726 h_mem.data.CopyFrom(mem.data, nnz);
735 #if MFEM_HYPRE_VERSION < 21400
736 hypre_TFree(h_mat->i);
737 #elif MFEM_HYPRE_VERSION < 21800
738 hypre_TFree(h_mat->i, HYPRE_MEMORY_SHARED);
740 hypre_TFree(h_mat->i, h_mat->memory_location);
742 if (h_mat->owns_data)
744 #if MFEM_HYPRE_VERSION < 21400
745 hypre_TFree(h_mat->j);
746 hypre_TFree(h_mat->data);
747 #elif MFEM_HYPRE_VERSION < 21800
748 hypre_TFree(h_mat->j, HYPRE_MEMORY_SHARED);
749 hypre_TFree(h_mat->data, HYPRE_MEMORY_SHARED);
751 hypre_TFree(h_mat->j, h_mat->memory_location);
752 hypre_TFree(h_mat->data, h_mat->memory_location);
756 h_mat->i = mem.I.ReadWrite(hypre_mc, nr1);
757 h_mat->j = mem.J.ReadWrite(hypre_mc, nnz);
758 h_mat->data = mem.data.ReadWrite(hypre_mc, nnz);
759 h_mat->owns_data = 0;
760 #if MFEM_HYPRE_VERSION >= 21800
761 h_mat->memory_location = HYPRE_MEMORY_DEVICE;
771 :
Operator(diag->Height(), diag->Width())
774 A = hypre_ParCSRMatrixCreate(comm, glob_size, glob_size, row_starts,
776 hypre_ParCSRMatrixSetDataOwner(A,1);
777 #if MFEM_HYPRE_VERSION <= 22200
778 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
779 hypre_ParCSRMatrixSetColStartsOwner(A,0);
782 hypre_CSRMatrixSetDataOwner(A->diag,0);
783 diagOwner = CopyCSR(diag, mem_diag, A->diag,
false);
784 hypre_CSRMatrixSetRownnz(A->diag);
786 hypre_CSRMatrixSetDataOwner(A->offd,1);
787 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
795 hypre_ParCSRMatrixSetNumNonzeros(A);
799 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
803 CopyCSR_J(A->diag->num_nonzeros, mem_diag, diag->
GetMemoryJ());
807 hypre_MatvecCommPkgCreate(A);
817 :
Operator(diag->Height(), diag->Width())
820 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
821 row_starts, col_starts,
823 hypre_ParCSRMatrixSetDataOwner(A,1);
824 #if MFEM_HYPRE_VERSION <= 22200
825 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
826 hypre_ParCSRMatrixSetColStartsOwner(A,0);
829 hypre_CSRMatrixSetDataOwner(A->diag,0);
830 diagOwner = CopyCSR(diag, mem_diag, A->diag,
false);
831 hypre_CSRMatrixSetRownnz(A->diag);
833 hypre_CSRMatrixSetDataOwner(A->offd,1);
834 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
837 hypre_ParCSRMatrixSetNumNonzeros(A);
840 if (row_starts == col_starts)
843 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
847 CopyCSR_J(A->diag->num_nonzeros, mem_diag, diag->
GetMemoryJ());
852 hypre_MatvecCommPkgCreate(A);
865 :
Operator(diag->Height(), diag->Width())
868 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
869 row_starts, col_starts,
872 hypre_ParCSRMatrixSetDataOwner(A,1);
873 #if MFEM_HYPRE_VERSION <= 22200
874 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
875 hypre_ParCSRMatrixSetColStartsOwner(A,0);
878 hypre_CSRMatrixSetDataOwner(A->diag,0);
879 diagOwner = CopyCSR(diag, mem_diag, A->diag, own_diag_offd);
880 if (own_diag_offd) {
delete diag; }
881 hypre_CSRMatrixSetRownnz(A->diag);
883 hypre_CSRMatrixSetDataOwner(A->offd,0);
884 offdOwner = CopyCSR(offd, mem_offd, A->offd, own_diag_offd);
885 if (own_diag_offd) {
delete offd; }
886 hypre_CSRMatrixSetRownnz(A->offd);
888 hypre_ParCSRMatrixColMapOffd(A) = cmap;
892 hypre_ParCSRMatrixSetNumNonzeros(A);
895 if (row_starts == col_starts)
898 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
902 CopyCSR_J(A->diag->num_nonzeros, mem_diag, diag->
GetMemoryJ());
907 hypre_MatvecCommPkgCreate(A);
916 HYPRE_Int *diag_i, HYPRE_Int *diag_j,
double *diag_data,
917 HYPRE_Int *offd_i, HYPRE_Int *offd_j,
double *offd_data,
922 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
923 row_starts, col_starts, offd_num_cols, 0, 0);
924 hypre_ParCSRMatrixSetDataOwner(A,1);
925 #if MFEM_HYPRE_VERSION <= 22200
926 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
927 hypre_ParCSRMatrixSetColStartsOwner(A,0);
930 HYPRE_Int local_num_rows = hypre_CSRMatrixNumRows(A->diag);
932 hypre_CSRMatrixSetDataOwner(A->diag, hypre_arrays);
933 hypre_CSRMatrixI(A->diag) = diag_i;
934 hypre_CSRMatrixJ(A->diag) = diag_j;
935 hypre_CSRMatrixData(A->diag) = diag_data;
936 hypre_CSRMatrixNumNonzeros(A->diag) = diag_i[local_num_rows];
937 #ifdef HYPRE_USING_GPU
938 hypre_CSRMatrixMemoryLocation(A->diag) = HYPRE_MEMORY_HOST;
941 hypre_CSRMatrixSetDataOwner(A->offd, hypre_arrays);
942 hypre_CSRMatrixI(A->offd) = offd_i;
943 hypre_CSRMatrixJ(A->offd) = offd_j;
944 hypre_CSRMatrixData(A->offd) = offd_data;
945 hypre_CSRMatrixNumNonzeros(A->offd) = offd_i[local_num_rows];
946 #ifdef HYPRE_USING_GPU
947 hypre_CSRMatrixMemoryLocation(A->offd) = HYPRE_MEMORY_HOST;
950 hypre_ParCSRMatrixColMapOffd(A) = offd_col_map;
952 colMapOwner = hypre_arrays ? -1 : 1;
954 hypre_ParCSRMatrixSetNumNonzeros(A);
957 if (row_starts == col_starts)
959 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
962 hypre_MatvecCommPkgCreate(A);
970 diagOwner = HypreCsrToMem(A->diag, host_mt,
true, mem_diag);
971 offdOwner = HypreCsrToMem(A->offd, host_mt,
true, mem_offd);
976 diagOwner = HypreCsrToMem(A->diag, host_mt,
false, mem_diag);
977 offdOwner = HypreCsrToMem(A->offd, host_mt,
false, mem_offd);
981 hypre_CSRMatrixSetRownnz(A->diag);
982 hypre_CSRMatrixSetRownnz(A->offd);
991 MFEM_ASSERT(sm_a != NULL,
"invalid input");
992 MFEM_VERIFY(!HYPRE_AssumedPartitionCheck(),
993 "this method can not be used with assumed partition");
997 hypre_CSRMatrix *csr_a;
998 csr_a = hypre_CSRMatrixCreate(sm_a ->
Height(), sm_a ->
Width(),
999 sm_a -> NumNonZeroElems());
1001 hypre_CSRMatrixSetDataOwner(csr_a,0);
1003 CopyCSR(sm_a, mem_a, csr_a,
false);
1004 hypre_CSRMatrixSetRownnz(csr_a);
1008 hypre_ParCSRMatrix *new_A =
1009 hypre_CSRMatrixToParCSRMatrix(comm, csr_a, row_starts, col_starts);
1015 hypre_CSRMatrixI(csr_a) = NULL;
1016 hypre_CSRMatrixDestroy(csr_a);
1019 if (row_starts == col_starts)
1021 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(new_A));
1024 hypre_MatvecCommPkgCreate(A);
1039 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
1040 row_starts, col_starts, 0, nnz, 0);
1041 hypre_ParCSRMatrixSetDataOwner(A,1);
1042 #if MFEM_HYPRE_VERSION <= 22200
1043 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
1044 hypre_ParCSRMatrixSetColStartsOwner(A,0);
1047 hypre_CSRMatrixSetDataOwner(A->diag,0);
1048 diagOwner = CopyBoolCSR(diag, mem_diag, A->diag);
1049 hypre_CSRMatrixSetRownnz(A->diag);
1051 hypre_CSRMatrixSetDataOwner(A->offd,1);
1052 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Size()+1);
1055 hypre_ParCSRMatrixSetNumNonzeros(A);
1058 if (row_starts == col_starts)
1061 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1068 hypre_MatvecCommPkgCreate(A);
1078 HYPRE_Int *i_diag, HYPRE_Int *j_diag,
1079 HYPRE_Int *i_offd, HYPRE_Int *j_offd,
1082 HYPRE_Int diag_nnz, offd_nnz;
1085 if (HYPRE_AssumedPartitionCheck())
1087 diag_nnz = i_diag[row[1]-row[0]];
1088 offd_nnz = i_offd[row[1]-row[0]];
1090 A = hypre_ParCSRMatrixCreate(comm, row[2], col[2], row, col,
1091 cmap_size, diag_nnz, offd_nnz);
1095 diag_nnz = i_diag[row[
id+1]-row[id]];
1096 offd_nnz = i_offd[row[
id+1]-row[id]];
1098 A = hypre_ParCSRMatrixCreate(comm, row[np], col[np], row, col,
1099 cmap_size, diag_nnz, offd_nnz);
1102 hypre_ParCSRMatrixSetDataOwner(A,1);
1103 #if MFEM_HYPRE_VERSION <= 22200
1104 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
1105 hypre_ParCSRMatrixSetColStartsOwner(A,0);
1109 for (HYPRE_Int i = 0; i < diag_nnz; i++)
1111 mem_diag.
data[i] = 1.0;
1115 for (HYPRE_Int i = 0; i < offd_nnz; i++)
1117 mem_offd.
data[i] = 1.0;
1120 hypre_CSRMatrixSetDataOwner(A->diag,0);
1121 hypre_CSRMatrixI(A->diag) = i_diag;
1122 hypre_CSRMatrixJ(A->diag) = j_diag;
1123 hypre_CSRMatrixData(A->diag) = mem_diag.
data;
1124 #ifdef HYPRE_USING_GPU
1125 hypre_CSRMatrixMemoryLocation(A->diag) = HYPRE_MEMORY_HOST;
1128 hypre_CSRMatrixSetDataOwner(A->offd,0);
1129 hypre_CSRMatrixI(A->offd) = i_offd;
1130 hypre_CSRMatrixJ(A->offd) = j_offd;
1131 hypre_CSRMatrixData(A->offd) = mem_offd.
data;
1132 #ifdef HYPRE_USING_GPU
1133 hypre_CSRMatrixMemoryLocation(A->offd) = HYPRE_MEMORY_HOST;
1136 hypre_ParCSRMatrixColMapOffd(A) = cmap;
1140 hypre_ParCSRMatrixSetNumNonzeros(A);
1145 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1148 hypre_MatvecCommPkgCreate(A);
1154 diagOwner = HypreCsrToMem(A->diag, host_mt,
true, mem_diag);
1155 offdOwner = HypreCsrToMem(A->offd, host_mt,
true, mem_offd);
1158 hypre_CSRMatrixSetRownnz(A->diag);
1159 hypre_CSRMatrixSetRownnz(A->offd);
1178 if (HYPRE_AssumedPartitionCheck())
1181 my_col_start = cols[0];
1182 my_col_end = cols[1];
1187 MPI_Comm_rank(comm, &myid);
1188 MPI_Comm_size(comm, &part_size);
1190 my_col_start = cols[myid];
1191 my_col_end = cols[myid+1];
1198 row_starts = col_starts = mfem_hypre_TAlloc_host(
HYPRE_BigInt, part_size);
1199 for (
int i = 0; i < part_size; i++)
1201 row_starts[i] = rows[i];
1206 row_starts = mfem_hypre_TAlloc_host(
HYPRE_BigInt, part_size);
1207 col_starts = mfem_hypre_TAlloc_host(
HYPRE_BigInt, part_size);
1208 for (
int i = 0; i < part_size; i++)
1210 row_starts[i] = rows[i];
1211 col_starts[i] = cols[i];
1217 HYPRE_Int diag_nnz = 0, offd_nnz = 0, offd_num_cols = 0;
1218 map<HYPRE_BigInt, HYPRE_Int> offd_map;
1219 for (HYPRE_Int j = 0, loc_nnz = I[nrows]; j < loc_nnz; j++)
1222 if (my_col_start <= glob_col && glob_col < my_col_end)
1228 offd_map.insert(pair<const HYPRE_BigInt, HYPRE_Int>(glob_col, -1));
1233 for (
auto it = offd_map.begin(); it != offd_map.end(); ++it)
1235 it->second = offd_num_cols++;
1239 A = hypre_ParCSRMatrixCreate(comm, glob_nrows, glob_ncols,
1240 row_starts, col_starts, offd_num_cols,
1241 diag_nnz, offd_nnz);
1242 hypre_ParCSRMatrixInitialize(A);
1248 HYPRE_Int *diag_i, *diag_j, *offd_i, *offd_j;
1250 double *diag_data, *offd_data;
1251 diag_i = A->diag->i;
1252 diag_j = A->diag->j;
1253 diag_data = A->diag->data;
1254 offd_i = A->offd->i;
1255 offd_j = A->offd->j;
1256 offd_data = A->offd->data;
1257 offd_col_map = A->col_map_offd;
1259 diag_nnz = offd_nnz = 0;
1260 for (HYPRE_Int i = 0, j = 0; i < nrows; i++)
1262 diag_i[i] = diag_nnz;
1263 offd_i[i] = offd_nnz;
1264 for (HYPRE_Int j_end = I[i+1]; j < j_end; j++)
1267 if (my_col_start <= glob_col && glob_col < my_col_end)
1269 diag_j[diag_nnz] = glob_col - my_col_start;
1270 diag_data[diag_nnz] = data[j];
1275 offd_j[offd_nnz] = offd_map[glob_col];
1276 offd_data[offd_nnz] = data[j];
1281 diag_i[nrows] = diag_nnz;
1282 offd_i[nrows] = offd_nnz;
1283 for (
auto it = offd_map.begin(); it != offd_map.end(); ++it)
1285 offd_col_map[it->second] = it->first;
1288 hypre_ParCSRMatrixSetNumNonzeros(A);
1290 if (row_starts == col_starts)
1292 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1294 #if MFEM_HYPRE_VERSION > 22200
1295 mfem_hypre_TFree_host(row_starts);
1298 mfem_hypre_TFree_host(col_starts);
1301 hypre_MatvecCommPkgCreate(A);
1311 hypre_ParCSRMatrix *Ph =
static_cast<hypre_ParCSRMatrix *
>(P);
1316 A = hypre_ParCSRMatrixCompleteClone(Ph);
1318 hypre_ParCSRMatrixCopy(Ph, A, 1);
1326 hypre_ParCSRMatrixSetNumNonzeros(A);
1328 hypre_MatvecCommPkgCreate(A);
1357 MFEM_ASSERT(diagOwner < 0 && offdOwner < 0 && colMapOwner == -1,
"");
1358 MFEM_ASSERT(diagOwner == offdOwner,
"");
1359 MFEM_ASSERT(ParCSROwner,
"");
1360 hypre_ParCSRMatrix *R = A;
1361 #ifdef HYPRE_USING_GPU
1365 ParCSROwner =
false;
1393 colMapOwner = colmap;
1398 #if MFEM_HYPRE_VERSION <= 22200
1399 if (!A || hypre_ParCSRMatrixOwnsRowStarts(A) ||
1400 (hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
1401 hypre_ParCSRMatrixOwnsColStarts(A)))
1406 int row_starts_size;
1407 if (HYPRE_AssumedPartitionCheck())
1409 row_starts_size = 2;
1413 MPI_Comm_size(hypre_ParCSRMatrixComm(A), &row_starts_size);
1417 HYPRE_BigInt *old_row_starts = hypre_ParCSRMatrixRowStarts(A);
1420 for (
int i = 0; i < row_starts_size; i++)
1422 new_row_starts[i] = old_row_starts[i];
1425 hypre_ParCSRMatrixRowStarts(A) = new_row_starts;
1426 hypre_ParCSRMatrixOwnsRowStarts(A) = 1;
1428 if (hypre_ParCSRMatrixColStarts(A) == old_row_starts)
1430 hypre_ParCSRMatrixColStarts(A) = new_row_starts;
1431 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
1438 #if MFEM_HYPRE_VERSION <= 22200
1439 if (!A || hypre_ParCSRMatrixOwnsColStarts(A) ||
1440 (hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
1441 hypre_ParCSRMatrixOwnsRowStarts(A)))
1446 int col_starts_size;
1447 if (HYPRE_AssumedPartitionCheck())
1449 col_starts_size = 2;
1453 MPI_Comm_size(hypre_ParCSRMatrixComm(A), &col_starts_size);
1457 HYPRE_BigInt *old_col_starts = hypre_ParCSRMatrixColStarts(A);
1460 for (
int i = 0; i < col_starts_size; i++)
1462 new_col_starts[i] = old_col_starts[i];
1465 hypre_ParCSRMatrixColStarts(A) = new_col_starts;
1467 if (hypre_ParCSRMatrixRowStarts(A) == old_col_starts)
1469 hypre_ParCSRMatrixRowStarts(A) = new_col_starts;
1470 hypre_ParCSRMatrixOwnsRowStarts(A) = 1;
1471 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
1475 hypre_ParCSRMatrixOwnsColStarts(A) = 1;
1482 const int size =
Height();
1484 #ifdef HYPRE_USING_GPU
1487 MFEM_ASSERT(A->diag->memory_location == HYPRE_MEMORY_DEVICE,
"");
1488 double *d_diag = diag.
Write();
1489 const HYPRE_Int *A_diag_i = A->diag->i;
1490 const double *A_diag_d = A->diag->data;
1491 MFEM_FORALL(i, size, d_diag[i] = A_diag_d[A_diag_i[i]];);
1498 for (
int j = 0; j < size; j++)
1500 diag(j) = A->diag->data[A->diag->i[j]];
1501 MFEM_ASSERT(A->diag->j[A->diag->i[j]] == j,
1502 "the first entry in each row must be the diagonal one");
1508 static void MakeSparseMatrixWrapper(
int nrows,
int ncols,
1509 HYPRE_Int *I, HYPRE_Int *J,
double *data,
1512 #ifndef HYPRE_BIGINT
1513 SparseMatrix tmp(I, J, data, nrows, ncols,
false,
false,
false);
1516 for (
int i = 0; i <= nrows; i++)
1520 const int nnz = mI[nrows];
1521 int *mJ = Memory<int>(nnz);
1522 for (
int j = 0; j < nnz; j++)
1526 SparseMatrix tmp(mI, mJ, data, nrows, ncols,
true,
false,
false);
1531 static void MakeWrapper(
const hypre_CSRMatrix *mat,
1532 const MemoryIJData &mem,
1533 SparseMatrix &wrapper)
1541 MakeSparseMatrixWrapper(nrows, ncols,
1542 const_cast<HYPRE_Int*>(I),
1543 const_cast<HYPRE_Int*>(J),
1544 const_cast<double*>(data),
1550 MakeWrapper(A->diag, mem_diag, diag);
1555 MakeWrapper(A->offd, mem_offd, offd);
1556 cmap = A->col_map_offd;
1562 hypre_CSRMatrix *hypre_merged = hypre_MergeDiagAndOffd(A);
1566 #if MFEM_HYPRE_VERSION >= 21600
1567 hypre_CSRMatrixBigJtoJ(hypre_merged);
1569 MakeSparseMatrixWrapper(
1578 merged = merged_tmp;
1580 hypre_CSRMatrixDestroy(hypre_merged);
1584 bool interleaved_rows,
1585 bool interleaved_cols)
const
1590 hypre_ParCSRMatrix **hypre_blocks =
new hypre_ParCSRMatrix*[nr * nc];
1592 internal::hypre_ParCSRMatrixSplit(A, nr, nc, hypre_blocks,
1593 interleaved_rows, interleaved_cols);
1596 for (
int i = 0; i < nr; i++)
1598 for (
int j = 0; j < nc; j++)
1604 delete [] hypre_blocks;
1609 hypre_ParCSRMatrix * At;
1610 hypre_ParCSRMatrixTranspose(A, &At, 1);
1611 hypre_ParCSRMatrixSetNumNonzeros(At);
1613 if (!hypre_ParCSRMatrixCommPkg(At)) { hypre_MatvecCommPkgCreate(At); }
1619 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(At));
1625 #if MFEM_HYPRE_VERSION >= 21800
1627 double threshold)
const
1635 hypre_MatvecCommPkgCreate(A);
1638 hypre_ParCSRMatrix *submat;
1641 int local_num_vars = hypre_CSRMatrixNumRows(hypre_ParCSRMatrixDiag(A));
1644 #ifdef hypre_IntArrayData
1646 hypre_IntArray *CF_marker;
1648 CF_marker = hypre_IntArrayCreate(local_num_vars);
1649 hypre_IntArrayInitialize_v2(CF_marker, HYPRE_MEMORY_HOST);
1650 hypre_IntArraySetConstantValues(CF_marker, 1);
1655 for (
int j=0; j<indices.
Size(); j++)
1657 if (indices[j] > local_num_vars)
1659 MFEM_WARNING(
"WARNING : " << indices[j] <<
" > " << local_num_vars);
1661 #ifdef hypre_IntArrayData
1662 hypre_IntArrayData(CF_marker)[indices[j]] = -1;
1664 CF_marker[indices[j]] = -1;
1669 #if (MFEM_HYPRE_VERSION > 22300) || (MFEM_HYPRE_VERSION == 22300 && HYPRE_DEVELOP_NUMBER >=8)
1672 hypre_BoomerAMGCoarseParms(MPI_COMM_WORLD, local_num_vars, 1, NULL,
1673 CF_marker, NULL, cpts_global);
1676 hypre_BoomerAMGCoarseParms(MPI_COMM_WORLD, local_num_vars, 1, NULL,
1677 CF_marker, NULL, &cpts_global);
1681 #ifdef hypre_IntArrayData
1682 hypre_ParCSRMatrixExtractSubmatrixFC(A, hypre_IntArrayData(CF_marker),
1683 cpts_global,
"FF", &submat,
1686 hypre_ParCSRMatrixExtractSubmatrixFC(A, CF_marker, cpts_global,
1687 "FF", &submat, threshold);
1690 #if (MFEM_HYPRE_VERSION <= 22300) && !(MFEM_HYPRE_VERSION == 22300 && HYPRE_DEVELOP_NUMBER >=8)
1691 mfem_hypre_TFree(cpts_global);
1693 #ifdef hypre_IntArrayData
1694 hypre_IntArrayDestroy(CF_marker);
1705 #if (MFEM_HYPRE_VERSION == 22500 && HYPRE_DEVELOP_NUMBER >= 1) || \
1706 (MFEM_HYPRE_VERSION > 22500)
1707 #ifdef HYPRE_USING_GPU
1708 hypre_ParCSRMatrixLocalTranspose(A);
1715 #if (MFEM_HYPRE_VERSION == 22500 && HYPRE_DEVELOP_NUMBER >= 1) || \
1716 (MFEM_HYPRE_VERSION > 22500)
1717 #ifdef HYPRE_USING_GPU
1720 hypre_CSRMatrixDestroy(A->diagT);
1725 hypre_CSRMatrixDestroy(A->offdT);
1733 double a,
double b)
const
1737 return hypre_ParCSRMatrixMatvec(a, A, x, b, y);
1742 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1743 <<
", expected size = " <<
Width());
1744 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1745 <<
", expected size = " <<
Height());
1792 hypre_ParCSRMatrixMatvec(a, A, *X, b, *Y);
1794 if (!yshallow) { y = *Y; }
1800 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
1801 <<
", expected size = " <<
Height());
1802 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
1803 <<
", expected size = " <<
Width());
1856 hypre_ParCSRMatrixMatvecT(a, A, *Y, b, *X);
1858 if (!yshallow) { y = *X; }
1862 double a,
double b)
const
1864 return hypre_ParCSRMatrixMatvec(a, A, (hypre_ParVector *) x, b,
1865 (hypre_ParVector *) y);
1869 double a,
double b)
const
1874 return hypre_ParCSRMatrixMatvecT(a, A, x, b, y);
1880 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1881 <<
", expected size = " <<
Width());
1882 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1883 <<
", expected size = " <<
Height());
1889 internal::hypre_ParCSRMatrixAbsMatvec(A, a, const_cast<double*>(x_data),
1897 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
1898 <<
", expected size = " <<
Height());
1899 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
1900 <<
", expected size = " <<
Width());
1906 internal::hypre_ParCSRMatrixAbsMatvecT(A, a, const_cast<double*>(x_data),
1914 const bool assumed_partition = HYPRE_AssumedPartitionCheck();
1915 const bool row_starts_given = (row_starts != NULL);
1916 if (!row_starts_given)
1918 row_starts = hypre_ParCSRMatrixRowStarts(A);
1919 MFEM_VERIFY(D.
Height() == hypre_CSRMatrixNumRows(A->diag),
1920 "the matrix D is NOT compatible with the row starts of"
1921 " this HypreParMatrix, row_starts must be given.");
1926 if (assumed_partition)
1932 MPI_Comm_rank(
GetComm(), &offset);
1934 int local_num_rows = row_starts[offset+1]-row_starts[offset];
1935 MFEM_VERIFY(local_num_rows == D.
Height(),
"the number of rows in D is "
1936 " not compatible with the given row_starts");
1943 if (assumed_partition)
1946 if (row_starts_given)
1948 global_num_rows = row_starts[2];
1955 global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
1960 MPI_Comm_size(
GetComm(), &part_size);
1961 global_num_rows = row_starts[part_size];
1965 HYPRE_BigInt *col_starts = hypre_ParCSRMatrixColStarts(A);
1971 GetOffd(A_offd, col_map_offd);
1981 DuplicateAs<HYPRE_BigInt>(row_starts, part_size,
false);
1983 (row_starts == col_starts ? new_row_starts :
1984 DuplicateAs<HYPRE_BigInt>(col_starts, part_size,
false));
1986 DuplicateAs<HYPRE_BigInt>(col_map_offd, A_offd.
Width());
1990 const bool own_diag_offd =
true;
1995 global_num_rows, hypre_ParCSRMatrixGlobalNumCols(A),
1996 new_row_starts, new_col_starts,
1997 DA_diag, DA_offd, new_col_map_offd,
2000 #if MFEM_HYPRE_VERSION <= 22200
2002 hypre_ParCSRMatrixSetRowStartsOwner(DA->A, 1);
2003 hypre_ParCSRMatrixSetColStartsOwner(DA->A, 1);
2005 mfem_hypre_TFree_host(new_row_starts);
2006 mfem_hypre_TFree_host(new_col_starts);
2008 DA->colMapOwner = 1;
2015 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
2020 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
2022 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
2029 double *Adiag_data = hypre_CSRMatrixData(A->diag);
2030 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
2032 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
2033 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
2036 for (
int i(0); i < size; ++i)
2039 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
2041 Adiag_data[jj] *= val;
2043 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
2045 Aoffd_data[jj] *= val;
2054 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
2059 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
2061 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
2068 double *Adiag_data = hypre_CSRMatrixData(A->diag);
2069 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
2072 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
2073 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
2076 for (
int i(0); i < size; ++i)
2081 mfem_error(
"HypreParMatrix::InvDiagScale : Division by 0");
2085 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
2087 Adiag_data[jj] *= val;
2089 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
2091 Aoffd_data[jj] *= val;
2100 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
2107 HYPRE_Int size=hypre_CSRMatrixNumRows(A->diag);
2110 double *Adiag_data = hypre_CSRMatrixData(A->diag);
2111 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
2112 for (jj = 0; jj < Adiag_i[size]; ++jj)
2114 Adiag_data[jj] *=
s;
2117 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
2118 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
2119 for (jj = 0; jj < Aoffd_i[size]; ++jj)
2121 Aoffd_data[jj] *=
s;
2127 static void get_sorted_rows_cols(
const Array<int> &rows_cols,
2133 for (
int i = 0; i < rows_cols.
Size(); i++)
2135 hypre_sorted[i] = rows_cols[i];
2136 if (i && rows_cols[i-1] > rows_cols[i]) { sorted =
false; }
2138 if (!sorted) { hypre_sorted.
Sort(); }
2146 hypre_CSRMatrix * csr_A;
2147 hypre_CSRMatrix * csr_A_wo_z;
2148 hypre_ParCSRMatrix * parcsr_A_ptr;
2153 comm = hypre_ParCSRMatrixComm(A);
2155 ierr += hypre_ParCSRMatrixGetLocalRange(A,
2156 &row_start,&row_end,
2157 &col_start,&col_end );
2159 row_starts = hypre_ParCSRMatrixRowStarts(A);
2160 col_starts = hypre_ParCSRMatrixColStarts(A);
2162 #if MFEM_HYPRE_VERSION <= 22200
2163 bool old_owns_row = hypre_ParCSRMatrixOwnsRowStarts(A);
2164 bool old_owns_col = hypre_ParCSRMatrixOwnsColStarts(A);
2166 HYPRE_BigInt global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
2167 HYPRE_BigInt global_num_cols = hypre_ParCSRMatrixGlobalNumCols(A);
2168 parcsr_A_ptr = hypre_ParCSRMatrixCreate(comm, global_num_rows,
2170 row_starts, col_starts,
2172 #if MFEM_HYPRE_VERSION <= 22200
2173 hypre_ParCSRMatrixOwnsRowStarts(parcsr_A_ptr) = old_owns_row;
2174 hypre_ParCSRMatrixOwnsColStarts(parcsr_A_ptr) = old_owns_col;
2175 hypre_ParCSRMatrixOwnsRowStarts(A) = 0;
2176 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
2179 csr_A = hypre_MergeDiagAndOffd(A);
2185 csr_A_wo_z = hypre_CSRMatrixDeleteZeros(csr_A,threshold);
2189 if (csr_A_wo_z == NULL)
2195 ierr += hypre_CSRMatrixDestroy(csr_A);
2201 ierr += GenerateDiagAndOffd(csr_A_wo_z,parcsr_A_ptr,
2204 ierr += hypre_CSRMatrixDestroy(csr_A_wo_z);
2206 MFEM_VERIFY(ierr == 0,
"");
2210 hypre_ParCSRMatrixSetNumNonzeros(A);
2212 #if MFEM_HYPRE_VERSION <= 22200
2213 if (row_starts == col_starts)
2215 if ((row_starts[0] == col_starts[0]) &&
2216 (row_starts[1] == col_starts[1]))
2219 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
2221 if (!hypre_ParCSRMatrixCommPkg(A)) { hypre_MatvecCommPkgCreate(A); }
2228 HYPRE_Int old_err = hypre_error_flag;
2229 hypre_error_flag = 0;
2231 #if MFEM_HYPRE_VERSION < 21400
2233 double threshold = 0.0;
2236 HYPRE_Int *diag_I = A->diag->i, *offd_I = A->offd->i;
2237 double *diag_d = A->diag->data, *offd_d = A->offd->data;
2238 HYPRE_Int local_num_rows = A->diag->num_rows;
2239 double max_l2_row_norm = 0.0;
2241 for (HYPRE_Int r = 0; r < local_num_rows; r++)
2244 double l2_row_norm = row.
Norml2();
2246 l2_row_norm = std::hypot(l2_row_norm, row.
Norml2());
2247 max_l2_row_norm = std::max(max_l2_row_norm, l2_row_norm);
2249 double loc_max_l2_row_norm = max_l2_row_norm;
2250 MPI_Allreduce(&loc_max_l2_row_norm, &max_l2_row_norm, 1, MPI_DOUBLE,
2252 threshold = tol * max_l2_row_norm;
2257 #elif MFEM_HYPRE_VERSION < 21800
2259 HYPRE_Int err_flag = hypre_ParCSRMatrixDropSmallEntries(A, tol);
2260 MFEM_VERIFY(!err_flag,
"error encountered: error code = " << err_flag);
2264 HYPRE_Int err_flag = hypre_ParCSRMatrixDropSmallEntries(A, tol, 2);
2265 MFEM_VERIFY(!err_flag,
"error encountered: error code = " << err_flag);
2269 hypre_error_flag = old_err;
2277 get_sorted_rows_cols(rows_cols, rc_sorted);
2279 internal::hypre_ParCSRMatrixEliminateAXB(
2286 get_sorted_rows_cols(rows_cols, rc_sorted);
2288 hypre_ParCSRMatrix* Ae;
2290 internal::hypre_ParCSRMatrixEliminateAAe(
2300 get_sorted_rows_cols(cols, rc_sorted);
2302 hypre_ParCSRMatrix* Ae;
2304 internal::hypre_ParCSRMatrixEliminateAAe(
2305 A, &Ae, rc_sorted.
Size(), rc_sorted.
GetData(), 1);
2313 if (rows.
Size() > 0)
2316 get_sorted_rows_cols(rows, r_sorted);
2318 internal::hypre_ParCSRMatrixEliminateRows(A, r_sorted.
Size(),
2329 Ae.
Mult(-1.0, x, 1.0, b);
2333 if (ess_dof_list.
Size() == 0) {
return; }
2336 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
2337 double *data = hypre_CSRMatrixData(A_diag);
2338 HYPRE_Int *I = hypre_CSRMatrixI(A_diag);
2340 HYPRE_Int *J = hypre_CSRMatrixJ(A_diag);
2341 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
2342 HYPRE_Int *I_offd = hypre_CSRMatrixI(A_offd);
2343 double *data_offd = hypre_CSRMatrixData(A_offd);
2350 for (
int i = 0; i < ess_dof_list.
Size(); i++)
2352 int r = ess_dof_list[i];
2353 b(r) = data[I[r]] * x(r);
2355 MFEM_ASSERT(I[r] < I[r+1],
"empty row found!");
2361 MFEM_ABORT(
"the diagonal entry must be the first entry in the row!");
2363 for (
int j = I[r]+1; j < I[r+1]; j++)
2367 MFEM_ABORT(
"all off-diagonal entries must be zero!");
2370 for (
int j = I_offd[r]; j < I_offd[r+1]; j++)
2372 if (data_offd[j] != 0.0)
2374 MFEM_ABORT(
"all off-diagonal entries must be zero!");
2385 hypre_ParCSRMatrix *A_hypre = *
this;
2388 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A_hypre);
2389 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A_hypre);
2391 HYPRE_Int diag_nrows = hypre_CSRMatrixNumRows(diag);
2392 HYPRE_Int offd_ncols = hypre_CSRMatrixNumCols(offd);
2394 const int n_ess_dofs = ess_dofs.
Size();
2400 hypre_ParCSRCommHandle *comm_handle;
2401 HYPRE_Int *int_buf_data, *eliminate_row, *eliminate_col;
2403 eliminate_row = mfem_hypre_CTAlloc(HYPRE_Int, diag_nrows);
2404 eliminate_col = mfem_hypre_CTAlloc(HYPRE_Int, offd_ncols);
2407 hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg(A_hypre);
2410 hypre_MatvecCommPkgCreate(A_hypre);
2411 comm_pkg = hypre_ParCSRMatrixCommPkg(A_hypre);
2415 MFEM_HYPRE_FORALL(i, diag_nrows, eliminate_row[i] = 0; );
2416 MFEM_HYPRE_FORALL(i, n_ess_dofs, eliminate_row[ess_dofs_d[i]] = 1; );
2421 HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg);
2422 HYPRE_Int int_buf_sz = hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends);
2423 int_buf_data = mfem_hypre_CTAlloc(HYPRE_Int, int_buf_sz);
2425 HYPRE_Int *send_map_elmts;
2426 #if defined(HYPRE_USING_GPU)
2427 hypre_ParCSRCommPkgCopySendMapElmtsToDevice(comm_pkg);
2428 send_map_elmts = hypre_ParCSRCommPkgDeviceSendMapElmts(comm_pkg);
2430 send_map_elmts = hypre_ParCSRCommPkgSendMapElmts(comm_pkg);
2432 MFEM_HYPRE_FORALL(i, int_buf_sz,
2434 int k = send_map_elmts[i];
2435 int_buf_data[i] = eliminate_row[k];
2438 #if defined(HYPRE_USING_GPU)
2440 comm_handle = hypre_ParCSRCommHandleCreate_v2(
2441 11, comm_pkg, HYPRE_MEMORY_DEVICE, int_buf_data,
2442 HYPRE_MEMORY_DEVICE, eliminate_col);
2444 comm_handle = hypre_ParCSRCommHandleCreate(
2445 11, comm_pkg, int_buf_data, eliminate_col );
2451 const auto I = diag->i;
2452 const auto J = diag->j;
2453 auto data = diag->data;
2455 MFEM_HYPRE_FORALL(i, n_ess_dofs,
2457 const int idof = ess_dofs_d[i];
2458 for (
int j=I[idof]; j<I[idof+1]; ++j)
2460 const int jdof = J[j];
2463 if (diag_policy == DiagonalPolicy::DIAG_ONE)
2467 else if (diag_policy == DiagonalPolicy::DIAG_ZERO)
2476 for (
int k=I[jdof]; k<I[jdof+1]; ++k)
2491 const auto I = offd->i;
2492 auto data = offd->data;
2493 MFEM_HYPRE_FORALL(i, n_ess_dofs,
2495 const int idof = ess_dofs_d[i];
2496 for (
int j=I[idof]; j<I[idof+1]; ++j)
2504 hypre_ParCSRCommHandleDestroy(comm_handle);
2505 mfem_hypre_TFree(int_buf_data);
2506 mfem_hypre_TFree(eliminate_row);
2510 const int nrows_offd = hypre_CSRMatrixNumRows(offd);
2511 const auto I = offd->i;
2512 const auto J = offd->j;
2513 auto data = offd->data;
2514 MFEM_HYPRE_FORALL(i, nrows_offd,
2516 for (
int j=I[i]; j<I[i+1]; ++j)
2518 data[j] *= 1 - eliminate_col[J[j]];
2523 mfem_hypre_TFree(eliminate_col);
2527 HYPRE_Int offj)
const
2530 hypre_ParCSRMatrixPrintIJ(A,offi,offj,fname);
2534 void HypreParMatrix::Read(MPI_Comm comm,
const char *fname)
2539 HYPRE_Int base_i, base_j;
2540 hypre_ParCSRMatrixReadIJ(comm, fname, &base_i, &base_j, &A);
2541 hypre_ParCSRMatrixSetNumNonzeros(A);
2543 if (!hypre_ParCSRMatrixCommPkg(A)) { hypre_MatvecCommPkgCreate(A); }
2554 HYPRE_IJMatrix A_ij;
2555 HYPRE_IJMatrixRead(fname, comm, 5555, &A_ij);
2557 HYPRE_ParCSRMatrix A_parcsr;
2558 HYPRE_IJMatrixGetObject(A_ij, (
void**) &A_parcsr);
2560 A = (hypre_ParCSRMatrix*)A_parcsr;
2562 hypre_ParCSRMatrixSetNumNonzeros(A);
2564 if (!hypre_ParCSRMatrixCommPkg(A)) { hypre_MatvecCommPkgCreate(A); }
2572 hypre_ParCSRCommPkg *comm_pkg = A->comm_pkg;
2573 MPI_Comm comm = A->comm;
2575 const int tag = 46801;
2577 MPI_Comm_rank(comm, &myid);
2578 MPI_Comm_size(comm, &nproc);
2582 MPI_Recv(&c, 1, MPI_CHAR, myid-1, tag, comm, MPI_STATUS_IGNORE);
2586 os <<
"\nHypreParMatrix: hypre_ParCSRCommPkg:\n";
2588 os <<
"Rank " << myid <<
":\n"
2589 " number of sends = " << comm_pkg->num_sends <<
2590 " (" <<
sizeof(double)*comm_pkg->send_map_starts[comm_pkg->num_sends] <<
2592 " number of recvs = " << comm_pkg->num_recvs <<
2593 " (" <<
sizeof(
double)*comm_pkg->recv_vec_starts[comm_pkg->num_recvs] <<
2595 if (myid != nproc-1)
2598 MPI_Send(&c, 1, MPI_CHAR, myid+1, tag, comm);
2611 os <<
"global number of rows : " << A->global_num_rows <<
'\n'
2612 <<
"global number of columns : " << A->global_num_cols <<
'\n'
2613 <<
"first row index : " << A->first_row_index <<
'\n'
2614 <<
" last row index : " << A->last_row_index <<
'\n'
2615 <<
"first col diag : " << A->first_col_diag <<
'\n'
2616 <<
" last col diag : " << A->last_col_diag <<
'\n'
2617 <<
"number of nonzeros : " << A->num_nonzeros <<
'\n';
2619 hypre_CSRMatrix *csr = A->diag;
2620 const char *csr_name =
"diag";
2621 for (
int m = 0; m < 2; m++)
2623 auto csr_nnz = csr->i[csr->num_rows];
2624 os << csr_name <<
" num rows : " << csr->num_rows <<
'\n'
2625 << csr_name <<
" num cols : " << csr->num_cols <<
'\n'
2626 << csr_name <<
" num nnz : " << csr->num_nonzeros <<
'\n'
2627 << csr_name <<
" i last : " << csr_nnz
2628 << (csr_nnz == csr->num_nonzeros ?
2629 " [good]" :
" [** BAD **]") <<
'\n';
2631 os << csr_name <<
" i hash : " << hf.
GetHash() <<
'\n';
2632 os << csr_name <<
" j hash : ";
2633 if (csr->j ==
nullptr)
2642 #if MFEM_HYPRE_VERSION >= 21600
2643 os << csr_name <<
" big j hash : ";
2644 if (csr->big_j ==
nullptr)
2654 os << csr_name <<
" data hash : ";
2655 if (csr->data ==
nullptr)
2669 hf.
AppendInts(A->col_map_offd, A->offd->num_cols);
2670 os <<
"col map offd hash : " << hf.
GetHash() <<
'\n';
2675 HYPRE_BigInt *A_col_map_offd = hypre_ParCSRMatrixColMapOffd(A);
2676 int size = hypre_CSRMatrixNumCols(hypre_ParCSRMatrixOffd(A));
2680 void HypreParMatrix::Destroy()
2682 if ( X != NULL ) {
delete X; }
2683 if ( Y != NULL ) {
delete Y; }
2687 if (A == NULL) {
return; }
2689 #ifdef HYPRE_USING_GPU
2690 if (ParCSROwner && (diagOwner < 0 || offdOwner < 0))
2698 MFEM_VERIFY(!(diagOwner < 0 && offdOwner < 0) || diagOwner == offdOwner,
2701 MemoryClass mc = (diagOwner == -1 || offdOwner == -1) ?
2703 Write(mc, diagOwner < 0, offdOwner <0);
2712 hypre_CSRMatrixI(A->diag) = NULL;
2713 hypre_CSRMatrixJ(A->diag) = NULL;
2714 hypre_CSRMatrixData(A->diag) = NULL;
2721 hypre_CSRMatrixI(A->offd) = NULL;
2722 hypre_CSRMatrixJ(A->offd) = NULL;
2723 hypre_CSRMatrixData(A->offd) = NULL;
2725 if (colMapOwner >= 0)
2727 if (colMapOwner & 1)
2731 hypre_ParCSRMatrixColMapOffd(A) = NULL;
2736 hypre_ParCSRMatrixDestroy(A);
2742 #ifndef HYPRE_BIGINT
2745 MFEM_CONTRACT_VAR(own_j);
2746 MFEM_ASSERT(own_i == own_j,
"Inconsistent ownership");
2760 #if MFEM_HYPRE_VERSION >= 21800
2769 hypre_ParCSRMatrix *C_hypre;
2770 hypre_ParcsrBdiagInvScal(*A, blocksize, &C_hypre);
2771 hypre_ParCSRMatrixDropSmallEntries(C_hypre, 1e-15, 1);
2781 hypre_ParVector *d_hypre;
2782 hypre_ParvecBdiagInvScal(b_Hypre, blocksize, &d_hypre, *A);
2790 #if MFEM_HYPRE_VERSION < 21400
2795 hypre_ParCSRMatrix *C_hypre =
2796 internal::hypre_ParCSRMatrixAdd(const_cast<HypreParMatrix &>(A),
2797 const_cast<HypreParMatrix &>(B));
2798 MFEM_VERIFY(C_hypre,
"error in hypre_ParCSRMatrixAdd");
2800 if (!hypre_ParCSRMatrixCommPkg(C_hypre)) { hypre_MatvecCommPkgCreate(C_hypre); }
2811 hypre_ParCSRMatrix * C = internal::hypre_ParCSRMatrixAdd(*A,*B);
2813 if (!hypre_ParCSRMatrixCommPkg(C)) { hypre_MatvecCommPkgCreate(C); }
2820 HypreParMatrix *
Add(
double alpha,
const HypreParMatrix &A,
2821 double beta,
const HypreParMatrix &B)
2823 hypre_ParCSRMatrix *C;
2824 #if MFEM_HYPRE_VERSION <= 22000
2825 hypre_ParcsrAdd(alpha, A, beta, B, &C);
2827 hypre_ParCSRMatrixAdd(alpha, A, beta, B, &C);
2829 if (!hypre_ParCSRMatrixCommPkg(C)) { hypre_MatvecCommPkgCreate(C); }
2831 return new HypreParMatrix(C);
2834 HypreParMatrix *
ParAdd(
const HypreParMatrix *A,
const HypreParMatrix *B)
2836 hypre_ParCSRMatrix *C;
2837 #if MFEM_HYPRE_VERSION <= 22000
2838 hypre_ParcsrAdd(1.0, *A, 1.0, *B, &C);
2840 hypre_ParCSRMatrixAdd(1.0, *A, 1.0, *B, &C);
2842 if (!hypre_ParCSRMatrixCommPkg(C)) { hypre_MatvecCommPkgCreate(C); }
2844 return new HypreParMatrix(C);
2852 hypre_ParCSRMatrix * ab;
2853 #ifdef HYPRE_USING_GPU
2854 ab = hypre_ParCSRMatMat(*A, *B);
2856 ab = hypre_ParMatmul(*A,*B);
2858 hypre_ParCSRMatrixSetNumNonzeros(ab);
2860 if (!hypre_ParCSRMatrixCommPkg(ab)) { hypre_MatvecCommPkgCreate(ab); }
2872 hypre_ParCSRMatrix * rap;
2874 #ifdef HYPRE_USING_GPU
2882 hypre_ParCSRMatrix *Q = hypre_ParCSRMatMat(*A,*P);
2883 const bool keepTranspose =
false;
2884 rap = hypre_ParCSRTMatMatKT(*P,Q,keepTranspose);
2885 hypre_ParCSRMatrixDestroy(Q);
2891 #if MFEM_HYPRE_VERSION <= 22200
2892 HYPRE_Int P_owns_its_col_starts =
2893 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
2896 hypre_BoomerAMGBuildCoarseOperator(*P,*A,*P,&rap);
2898 #if MFEM_HYPRE_VERSION <= 22200
2901 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
2902 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
2903 if (P_owns_its_col_starts)
2905 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
2910 hypre_ParCSRMatrixSetNumNonzeros(rap);
2919 hypre_ParCSRMatrix * rap;
2921 #ifdef HYPRE_USING_GPU
2923 hypre_ParCSRMatrix *Q = hypre_ParCSRMatMat(*A,*P);
2924 rap = hypre_ParCSRTMatMat(*Rt,Q);
2925 hypre_ParCSRMatrixDestroy(Q);
2928 #if MFEM_HYPRE_VERSION <= 22200
2929 HYPRE_Int P_owns_its_col_starts =
2930 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
2931 HYPRE_Int Rt_owns_its_col_starts =
2932 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*Rt));
2935 hypre_BoomerAMGBuildCoarseOperator(*Rt,*A,*P,&rap);
2937 #if MFEM_HYPRE_VERSION <= 22200
2940 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
2941 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
2942 if (P_owns_its_col_starts)
2944 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
2946 if (Rt_owns_its_col_starts)
2948 hypre_ParCSRMatrixSetColStartsOwner(*Rt, 1);
2953 hypre_ParCSRMatrixSetNumNonzeros(rap);
2962 const int num_loc,
const Array<int> &offsets,
2963 std::vector<int> &all_num_loc,
const int numBlocks,
2964 std::vector<std::vector<HYPRE_BigInt>> &blockProcOffsets,
2965 std::vector<HYPRE_BigInt> &procOffsets,
2966 std::vector<std::vector<int>> &procBlockOffsets,
2969 std::vector<std::vector<int>> all_block_num_loc(numBlocks);
2971 MPI_Allgather(&num_loc, 1, MPI_INT, all_num_loc.data(), 1, MPI_INT, comm);
2973 for (
int j = 0; j < numBlocks; ++j)
2975 all_block_num_loc[j].resize(nprocs);
2976 blockProcOffsets[j].resize(nprocs);
2978 const int blockNumRows = offsets[j + 1] - offsets[j];
2979 MPI_Allgather(&blockNumRows, 1, MPI_INT, all_block_num_loc[j].data(), 1,
2981 blockProcOffsets[j][0] = 0;
2982 for (
int i = 0; i < nprocs - 1; ++i)
2984 blockProcOffsets[j][i + 1] = blockProcOffsets[j][i]
2985 + all_block_num_loc[j][i];
2992 for (
int i = 0; i < nprocs; ++i)
2994 globalNum += all_num_loc[i];
2997 MFEM_VERIFY(globalNum >= 0,
"overflow in global size");
3001 firstLocal += all_num_loc[i];
3006 procOffsets[i + 1] = procOffsets[i] + all_num_loc[i];
3009 procBlockOffsets[i].resize(numBlocks);
3010 procBlockOffsets[i][0] = 0;
3011 for (
int j = 1; j < numBlocks; ++j)
3013 procBlockOffsets[i][j] = procBlockOffsets[i][j - 1]
3014 + all_block_num_loc[j - 1][i];
3022 const int numBlockRows = blocks.
NumRows();
3023 const int numBlockCols = blocks.
NumCols();
3025 MFEM_VERIFY(numBlockRows > 0 &&
3026 numBlockCols > 0,
"Invalid input to HypreParMatrixFromBlocks");
3028 if (blockCoeff != NULL)
3030 MFEM_VERIFY(numBlockRows == blockCoeff->
NumRows() &&
3031 numBlockCols == blockCoeff->
NumCols(),
3032 "Invalid input to HypreParMatrixFromBlocks");
3038 int nonNullBlockRow0 = -1;
3039 for (
int j=0; j<numBlockCols; ++j)
3041 if (blocks(0,j) != NULL)
3043 nonNullBlockRow0 = j;
3048 MFEM_VERIFY(nonNullBlockRow0 >= 0,
"Null row of blocks");
3049 MPI_Comm comm = blocks(0,nonNullBlockRow0)->GetComm();
3054 for (
int i=0; i<numBlockRows; ++i)
3056 for (
int j=0; j<numBlockCols; ++j)
3058 if (blocks(i,j) != NULL)
3060 const int nrows = blocks(i,j)->
NumRows();
3061 const int ncols = blocks(i,j)->
NumCols();
3063 MFEM_VERIFY(nrows > 0 &&
3064 ncols > 0,
"Invalid block in HypreParMatrixFromBlocks");
3066 if (rowOffsets[i+1] == 0)
3068 rowOffsets[i+1] = nrows;
3072 MFEM_VERIFY(rowOffsets[i+1] == nrows,
3073 "Inconsistent blocks in HypreParMatrixFromBlocks");
3076 if (colOffsets[j+1] == 0)
3078 colOffsets[j+1] = ncols;
3082 MFEM_VERIFY(colOffsets[j+1] == ncols,
3083 "Inconsistent blocks in HypreParMatrixFromBlocks");
3088 MFEM_VERIFY(rowOffsets[i+1] > 0,
"Invalid input blocks");
3089 rowOffsets[i+1] += rowOffsets[i];
3092 for (
int j=0; j<numBlockCols; ++j)
3094 MFEM_VERIFY(colOffsets[j+1] > 0,
"Invalid input blocks");
3095 colOffsets[j+1] += colOffsets[j];
3098 const int num_loc_rows = rowOffsets[numBlockRows];
3099 const int num_loc_cols = colOffsets[numBlockCols];
3102 MPI_Comm_rank(comm, &rank);
3103 MPI_Comm_size(comm, &nprocs);
3105 std::vector<int> all_num_loc_rows(nprocs);
3106 std::vector<int> all_num_loc_cols(nprocs);
3107 std::vector<HYPRE_BigInt> procRowOffsets(nprocs);
3108 std::vector<HYPRE_BigInt> procColOffsets(nprocs);
3109 std::vector<std::vector<HYPRE_BigInt>> blockRowProcOffsets(numBlockRows);
3110 std::vector<std::vector<HYPRE_BigInt>> blockColProcOffsets(numBlockCols);
3111 std::vector<std::vector<int>> procBlockRowOffsets(nprocs);
3112 std::vector<std::vector<int>> procBlockColOffsets(nprocs);
3114 HYPRE_BigInt first_loc_row, glob_nrows, first_loc_col, glob_ncols;
3116 all_num_loc_rows, numBlockRows, blockRowProcOffsets,
3117 procRowOffsets, procBlockRowOffsets, first_loc_row,
3121 all_num_loc_cols, numBlockCols, blockColProcOffsets,
3122 procColOffsets, procBlockColOffsets, first_loc_col,
3125 std::vector<int> opI(num_loc_rows + 1);
3126 std::vector<int> cnt(num_loc_rows);
3128 for (
int i = 0; i < num_loc_rows; ++i)
3134 opI[num_loc_rows] = 0;
3139 for (
int i = 0; i < numBlockRows; ++i)
3141 for (
int j = 0; j < numBlockCols; ++j)
3143 if (blocks(i, j) == NULL)
3145 csr_blocks(i, j) = NULL;
3149 blocks(i, j)->HostRead();
3150 csr_blocks(i, j) = hypre_MergeDiagAndOffd(*blocks(i, j));
3151 blocks(i, j)->HypreRead();
3153 for (
int k = 0; k < csr_blocks(i, j)->num_rows; ++k)
3155 opI[rowOffsets[i] + k + 1] +=
3156 csr_blocks(i, j)->i[k + 1] - csr_blocks(i, j)->i[k];
3163 for (
int i = 0; i < num_loc_rows; ++i)
3165 opI[i + 1] += opI[i];
3168 const int nnz = opI[num_loc_rows];
3170 std::vector<HYPRE_BigInt> opJ(nnz);
3171 std::vector<double> data(nnz);
3174 for (
int i = 0; i < numBlockRows; ++i)
3176 for (
int j = 0; j < numBlockCols; ++j)
3178 if (csr_blocks(i, j) != NULL)
3180 const int nrows = csr_blocks(i, j)->num_rows;
3181 const double cij = blockCoeff ? (*blockCoeff)(i, j) : 1.0;
3182 #if MFEM_HYPRE_VERSION >= 21600
3183 const bool usingBigJ = (csr_blocks(i, j)->big_j != NULL);
3186 for (
int k = 0; k < nrows; ++k)
3188 const int rowg = rowOffsets[i] + k;
3189 const int nnz_k = csr_blocks(i,j)->i[k+1]-csr_blocks(i,j)->i[k];
3190 const int osk = csr_blocks(i, j)->i[k];
3192 for (
int l = 0; l < nnz_k; ++l)
3195 #if MFEM_HYPRE_VERSION >= 21600
3196 const HYPRE_Int bcol = usingBigJ ?
3197 csr_blocks(i, j)->big_j[osk + l] :
3198 csr_blocks(i, j)->j[osk + l];
3200 const HYPRE_Int bcol = csr_blocks(i, j)->j[osk + l];
3204 const auto &offs = blockColProcOffsets[j];
3205 const int bcolproc =
3206 std::upper_bound(offs.begin() + 1, offs.end(), bcol)
3209 opJ[opI[rowg] + cnt[rowg]] = procColOffsets[bcolproc] +
3210 procBlockColOffsets[bcolproc][j]
3212 - blockColProcOffsets[j][bcolproc];
3213 data[opI[rowg] + cnt[rowg]] = cij * csr_blocks(i, j)->data[osk + l];
3221 for (
int i = 0; i < numBlockRows; ++i)
3223 for (
int j = 0; j < numBlockCols; ++j)
3225 if (csr_blocks(i, j) != NULL)
3227 hypre_CSRMatrixDestroy(csr_blocks(i, j));
3232 MFEM_VERIFY(HYPRE_AssumedPartitionCheck(),
3233 "only 'assumed partition' mode is supported");
3235 std::vector<HYPRE_BigInt> rowStarts2(2);
3236 rowStarts2[0] = first_loc_row;
3237 rowStarts2[1] = first_loc_row + all_num_loc_rows[rank];
3239 int square = std::equal(all_num_loc_rows.begin(), all_num_loc_rows.end(),
3240 all_num_loc_cols.begin());
3243 return new HypreParMatrix(comm, num_loc_rows, glob_nrows, glob_ncols,
3244 opI.data(), opJ.data(),
3251 std::vector<HYPRE_BigInt> colStarts2(2);
3252 colStarts2[0] = first_loc_col;
3253 colStarts2[1] = first_loc_col + all_num_loc_cols[rank];
3255 return new HypreParMatrix(comm, num_loc_rows, glob_nrows, glob_ncols,
3256 opI.data(), opJ.data(),
3283 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
3284 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
3286 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(u));
3287 double *r_data = hypre_VectorData(hypre_ParVectorLocalVector(r));
3289 for (
int i = 0; i < N; i++)
3292 hypre_ParVectorCopy(f, r);
3293 hypre_ParCSRMatrixMatvec(-1.0, A, u, 1.0, r);
3296 (0 == (i % 2)) ? coef = lambda : coef =
mu;
3298 for (HYPRE_Int j = 0; j < num_rows; j++)
3300 u_data[j] += coef*r_data[j] / max_eig;
3316 hypre_ParVector *x0,
3317 hypre_ParVector *x1,
3318 hypre_ParVector *x2,
3319 hypre_ParVector *x3)
3322 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
3323 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
3325 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(u));
3327 double *x0_data = hypre_VectorData(hypre_ParVectorLocalVector(x0));
3328 double *x1_data = hypre_VectorData(hypre_ParVectorLocalVector(x1));
3329 double *x2_data = hypre_VectorData(hypre_ParVectorLocalVector(x2));
3330 double *x3_data = hypre_VectorData(hypre_ParVectorLocalVector(x3));
3332 hypre_ParVectorCopy(u, x0);
3335 hypre_ParVectorCopy(f, x1);
3336 hypre_ParCSRMatrixMatvec(-1.0, A, x0, 1.0, x1);
3338 for (HYPRE_Int i = 0; i < num_rows; i++)
3340 x1_data[i] /= -max_eig;
3344 for (HYPRE_Int i = 0; i < num_rows; i++)
3346 x1_data[i] = x0_data[i] -x1_data[i];
3350 for (HYPRE_Int i = 0; i < num_rows; i++)
3352 x3_data[i] = fir_coeffs[0]*x0_data[i] +fir_coeffs[1]*x1_data[i];
3355 for (
int n = 2; n <= poly_order; n++)
3358 hypre_ParVectorCopy(f, x2);
3359 hypre_ParCSRMatrixMatvec(-1.0, A, x1, 1.0, x2);
3361 for (HYPRE_Int i = 0; i < num_rows; i++)
3363 x2_data[i] /= -max_eig;
3371 for (HYPRE_Int i = 0; i < num_rows; i++)
3373 x2_data[i] = (x1_data[i]-x0_data[i]) +(x1_data[i]-2*x2_data[i]);
3374 x3_data[i] += fir_coeffs[n]*x2_data[i];
3375 x0_data[i] = x1_data[i];
3376 x1_data[i] = x2_data[i];
3380 for (HYPRE_Int i = 0; i < num_rows; i++)
3382 u_data[i] = x3_data[i];
3403 B =
X =
V =
Z = NULL;
3411 int relax_times_,
double relax_weight_,
3412 double omega_,
int poly_order_,
3413 double poly_fraction_,
int eig_est_cg_iter_)
3425 B =
X =
V =
Z = NULL;
3436 type =
static_cast<int>(type_);
3447 int eig_est_cg_iter_)
3464 double a = -1,
b, c;
3465 if (!strcmp(name,
"Rectangular")) { a = 1.0,
b = 0.0, c = 0.0; }
3466 if (!strcmp(name,
"Hanning")) { a = 0.5,
b = 0.5, c = 0.0; }
3467 if (!strcmp(name,
"Hamming")) { a = 0.54,
b = 0.46, c = 0.0; }
3468 if (!strcmp(name,
"Blackman")) { a = 0.42,
b = 0.50, c = 0.08; }
3471 mfem_error(
"HypreSmoother::SetWindowByName : name not recognized!");
3489 mfem_error(
"HypreSmoother::SetOperator : not HypreParMatrix!");
3496 if (B) {
delete B; }
3497 if (
X) {
delete X; }
3498 if (
V) {
delete V; }
3499 if (
Z) {
delete Z; }
3507 X1 =
X0 =
Z =
V = B =
X = NULL;
3521 A->Mult(ones, diag);
3529 #if defined(HYPRE_USING_GPU)
3531 MFEM_GPU_FORALL(i,
height,
3533 d_l1_norms[i] = std::abs(d_l1_norms[i]);
3536 for (
int i = 0; i <
height; i++)
3553 #if MFEM_HYPRE_VERSION <= 22200
3562 else if (
type == 1001 ||
type == 1002)
3572 #if MFEM_HYPRE_VERSION <= 22200
3605 double* window_coeffs =
new double[
poly_order+1];
3606 double* cheby_coeffs =
new double[
poly_order+1];
3614 window_coeffs[i] = a + b*cos(t) +c*cos(2*t);
3618 double theta_pb = acos(1.0 -0.5*k_pb);
3620 cheby_coeffs[0] = (theta_pb +
sigma)/M_PI;
3623 double t = i*(theta_pb+
sigma);
3624 cheby_coeffs[i] = 2.0*sin(t)/(i*M_PI);
3629 fir_coeffs[i] = window_coeffs[i]*cheby_coeffs[i];
3632 delete[] window_coeffs;
3633 delete[] cheby_coeffs;
3640 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
3653 HYPRE_ParCSRDiagScale(NULL, *A, b, x);
3660 hypre_ParVectorSetConstantValues(x, 0.0);
3681 else if (
type == 1002)
3695 int hypre_type =
type;
3697 if (
type == 5) { hypre_type = 1; }
3701 hypre_ParCSRRelax(*A, b, hypre_type,
3708 hypre_ParCSRRelax(*A, b, hypre_type,
3723 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
3730 A -> GetGlobalNumRows(),
3732 A -> GetRowStarts());
3734 A -> GetGlobalNumCols(),
3736 A -> GetColStarts());
3750 B->WrapMemoryRead(
auxB);
3774 if (!xshallow) { x = *
X; }
3784 mfem_error(
"HypreSmoother::MultTranspose (...) : undefined!\n");
3790 if (B) {
delete B; }
3791 if (
X) {
delete X; }
3792 if (
V) {
delete V; }
3793 if (
Z) {
delete Z; }
3802 if (
X0) {
delete X0; }
3803 if (
X1) {
delete X1; }
3818 :
Solver(A_->Height(), A_->Width())
3833 MFEM_VERIFY(A != NULL,
"HypreParMatrix A is missing");
3838 nullptr, A->GetRowStarts());
3840 nullptr, A->GetColStarts());
3854 B->WrapMemoryRead(
auxB);
3883 MFEM_VERIFY(A != NULL,
"HypreParMatrix A is missing");
3885 HYPRE_Int err_flag =
SetupFcn()(*
this, *
A,
b, x);
3889 { MFEM_WARNING(
"Error during setup! Error code: " << err_flag); }
3893 MFEM_VERIFY(!err_flag,
"Error during setup! Error code: " << err_flag);
3895 hypre_error_flag = 0;
3903 if (!x_shallow) { x = *
X; }
3911 mfem_error(
"HypreSolver::Mult (...) : HypreParMatrix A is missing");
3918 hypre_ParVectorSetConstantValues(x, 0.0);
3930 { MFEM_WARNING(
"Error during solve! Error code: " << err_flag); }
3934 MFEM_VERIFY(!err_flag,
"Error during solve! Error code: " << err_flag);
3936 hypre_error_flag = 0;
3943 if (!x_shallow) { x = *
X; }
3948 if (B) {
delete B; }
3949 if (
X) {
delete X; }
3959 HYPRE_ParCSRPCGCreate(comm, &pcg_solver);
3968 HYPRE_ParCSRMatrixGetComm(*A, &comm);
3970 HYPRE_ParCSRPCGCreate(comm, &pcg_solver);
3976 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3997 HYPRE_PCGSetTol(pcg_solver, tol);
4002 HYPRE_PCGSetAbsoluteTol(pcg_solver, atol);
4007 HYPRE_PCGSetMaxIter(pcg_solver, max_iter);
4012 HYPRE_PCGSetLogging(pcg_solver, logging);
4017 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_lvl);
4022 precond = &precond_;
4024 HYPRE_ParCSRPCGSetPrecond(pcg_solver,
4032 HYPRE_PCGSetTwoNorm(pcg_solver, 1);
4033 if (res_frequency > 0)
4035 HYPRE_PCGSetRecomputeResidualP(pcg_solver, res_frequency);
4039 HYPRE_PCGSetResidualTol(pcg_solver, rtol);
4046 HYPRE_Int time_index = 0;
4047 HYPRE_Int num_iterations;
4048 double final_res_norm;
4050 HYPRE_Int print_level;
4052 HYPRE_PCGGetPrintLevel(pcg_solver, &print_level);
4053 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level%3);
4055 HYPRE_ParCSRMatrixGetComm(*A, &comm);
4060 hypre_ParVectorSetConstantValues(x, 0.0);
4068 if (print_level > 0 && print_level < 3)
4070 time_index = hypre_InitializeTiming(
"PCG Setup");
4071 hypre_BeginTiming(time_index);
4074 HYPRE_ParCSRPCGSetup(pcg_solver, *A, b, x);
4077 if (print_level > 0 && print_level < 3)
4079 hypre_EndTiming(time_index);
4080 hypre_PrintTiming(
"Setup phase times", comm);
4081 hypre_FinalizeTiming(time_index);
4082 hypre_ClearTiming();
4086 if (print_level > 0 && print_level < 3)
4088 time_index = hypre_InitializeTiming(
"PCG Solve");
4089 hypre_BeginTiming(time_index);
4092 HYPRE_ParCSRPCGSolve(pcg_solver, *A, b, x);
4094 if (print_level > 0)
4096 if (print_level < 3)
4098 hypre_EndTiming(time_index);
4099 hypre_PrintTiming(
"Solve phase times", comm);
4100 hypre_FinalizeTiming(time_index);
4101 hypre_ClearTiming();
4104 HYPRE_ParCSRPCGGetNumIterations(pcg_solver, &num_iterations);
4105 HYPRE_ParCSRPCGGetFinalRelativeResidualNorm(pcg_solver,
4108 MPI_Comm_rank(comm, &myid);
4112 mfem::out <<
"PCG Iterations = " << num_iterations << endl
4113 <<
"Final PCG Relative Residual Norm = " << final_res_norm
4117 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level);
4122 HYPRE_ParCSRPCGDestroy(pcg_solver);
4130 HYPRE_ParCSRGMRESCreate(comm, &gmres_solver);
4131 SetDefaultOptions();
4141 HYPRE_ParCSRMatrixGetComm(*A, &comm);
4143 HYPRE_ParCSRGMRESCreate(comm, &gmres_solver);
4144 SetDefaultOptions();
4147 void HypreGMRES::SetDefaultOptions()
4153 HYPRE_ParCSRGMRESSetKDim(gmres_solver, k_dim);
4154 HYPRE_ParCSRGMRESSetMaxIter(gmres_solver, max_iter);
4155 HYPRE_ParCSRGMRESSetTol(gmres_solver, tol);
4161 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4182 HYPRE_GMRESSetTol(gmres_solver, tol);
4187 HYPRE_GMRESSetAbsoluteTol(gmres_solver, tol);
4192 HYPRE_GMRESSetMaxIter(gmres_solver, max_iter);
4197 HYPRE_GMRESSetKDim(gmres_solver, k_dim);
4202 HYPRE_GMRESSetLogging(gmres_solver, logging);
4207 HYPRE_GMRESSetPrintLevel(gmres_solver, print_lvl);
4212 precond = &precond_;
4214 HYPRE_ParCSRGMRESSetPrecond(gmres_solver,
4223 HYPRE_Int time_index = 0;
4224 HYPRE_Int num_iterations;
4225 double final_res_norm;
4227 HYPRE_Int print_level;
4229 HYPRE_GMRESGetPrintLevel(gmres_solver, &print_level);
4231 HYPRE_ParCSRMatrixGetComm(*A, &comm);
4236 hypre_ParVectorSetConstantValues(x, 0.0);
4244 if (print_level > 0)
4246 time_index = hypre_InitializeTiming(
"GMRES Setup");
4247 hypre_BeginTiming(time_index);
4250 HYPRE_ParCSRGMRESSetup(gmres_solver, *A, b, x);
4253 if (print_level > 0)
4255 hypre_EndTiming(time_index);
4256 hypre_PrintTiming(
"Setup phase times", comm);
4257 hypre_FinalizeTiming(time_index);
4258 hypre_ClearTiming();
4262 if (print_level > 0)
4264 time_index = hypre_InitializeTiming(
"GMRES Solve");
4265 hypre_BeginTiming(time_index);
4268 HYPRE_ParCSRGMRESSolve(gmres_solver, *A, b, x);
4270 if (print_level > 0)
4272 hypre_EndTiming(time_index);
4273 hypre_PrintTiming(
"Solve phase times", comm);
4274 hypre_FinalizeTiming(time_index);
4275 hypre_ClearTiming();
4277 HYPRE_ParCSRGMRESGetNumIterations(gmres_solver, &num_iterations);
4278 HYPRE_ParCSRGMRESGetFinalRelativeResidualNorm(gmres_solver,
4281 MPI_Comm_rank(comm, &myid);
4285 mfem::out <<
"GMRES Iterations = " << num_iterations << endl
4286 <<
"Final GMRES Relative Residual Norm = " << final_res_norm
4294 HYPRE_ParCSRGMRESDestroy(gmres_solver);
4302 HYPRE_ParCSRFlexGMRESCreate(comm, &fgmres_solver);
4303 SetDefaultOptions();
4313 HYPRE_ParCSRMatrixGetComm(*A, &comm);
4315 HYPRE_ParCSRFlexGMRESCreate(comm, &fgmres_solver);
4316 SetDefaultOptions();
4319 void HypreFGMRES::SetDefaultOptions()
4325 HYPRE_ParCSRFlexGMRESSetKDim(fgmres_solver, k_dim);
4326 HYPRE_ParCSRFlexGMRESSetMaxIter(fgmres_solver, max_iter);
4327 HYPRE_ParCSRFlexGMRESSetTol(fgmres_solver, tol);
4333 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4354 HYPRE_ParCSRFlexGMRESSetTol(fgmres_solver, tol);
4359 HYPRE_ParCSRFlexGMRESSetMaxIter(fgmres_solver, max_iter);
4364 HYPRE_ParCSRFlexGMRESSetKDim(fgmres_solver, k_dim);
4369 HYPRE_ParCSRFlexGMRESSetLogging(fgmres_solver, logging);
4374 HYPRE_ParCSRFlexGMRESSetPrintLevel(fgmres_solver, print_lvl);
4379 precond = &precond_;
4380 HYPRE_ParCSRFlexGMRESSetPrecond(fgmres_solver,
4389 HYPRE_Int time_index = 0;
4390 HYPRE_Int num_iterations;
4391 double final_res_norm;
4393 HYPRE_Int print_level;
4395 HYPRE_FlexGMRESGetPrintLevel(fgmres_solver, &print_level);
4397 HYPRE_ParCSRMatrixGetComm(*A, &comm);
4402 hypre_ParVectorSetConstantValues(x, 0.0);
4410 if (print_level > 0)
4412 time_index = hypre_InitializeTiming(
"FGMRES Setup");
4413 hypre_BeginTiming(time_index);
4416 HYPRE_ParCSRFlexGMRESSetup(fgmres_solver, *A, b, x);
4419 if (print_level > 0)
4421 hypre_EndTiming(time_index);
4422 hypre_PrintTiming(
"Setup phase times", comm);
4423 hypre_FinalizeTiming(time_index);
4424 hypre_ClearTiming();
4428 if (print_level > 0)
4430 time_index = hypre_InitializeTiming(
"FGMRES Solve");
4431 hypre_BeginTiming(time_index);
4434 HYPRE_ParCSRFlexGMRESSolve(fgmres_solver, *A, b, x);
4436 if (print_level > 0)
4438 hypre_EndTiming(time_index);
4439 hypre_PrintTiming(
"Solve phase times", comm);
4440 hypre_FinalizeTiming(time_index);
4441 hypre_ClearTiming();
4443 HYPRE_ParCSRFlexGMRESGetNumIterations(fgmres_solver, &num_iterations);
4444 HYPRE_ParCSRFlexGMRESGetFinalRelativeResidualNorm(fgmres_solver,
4447 MPI_Comm_rank(comm, &myid);
4451 mfem::out <<
"FGMRES Iterations = " << num_iterations << endl
4452 <<
"Final FGMRES Relative Residual Norm = " << final_res_norm
4460 HYPRE_ParCSRFlexGMRESDestroy(fgmres_solver);
4467 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4484 HYPRE_ParaSailsCreate(comm, &sai_precond);
4485 SetDefaultOptions();
4492 HYPRE_ParCSRMatrixGetComm(A, &comm);
4494 HYPRE_ParaSailsCreate(comm, &sai_precond);
4495 SetDefaultOptions();
4498 void HypreParaSails::SetDefaultOptions()
4500 int sai_max_levels = 1;
4501 double sai_threshold = 0.1;
4502 double sai_filter = 0.1;
4504 double sai_loadbal = 0.0;
4506 int sai_logging = 1;
4508 HYPRE_ParaSailsSetParams(sai_precond, sai_threshold, sai_max_levels);
4509 HYPRE_ParaSailsSetFilter(sai_precond, sai_filter);
4510 HYPRE_ParaSailsSetSym(sai_precond, sai_sym);
4511 HYPRE_ParaSailsSetLoadbal(sai_precond, sai_loadbal);
4512 HYPRE_ParaSailsSetReuse(sai_precond, sai_reuse);
4513 HYPRE_ParaSailsSetLogging(sai_precond, sai_logging);
4516 void HypreParaSails::ResetSAIPrecond(MPI_Comm comm)
4518 HYPRE_Int sai_max_levels;
4519 HYPRE_Real sai_threshold;
4520 HYPRE_Real sai_filter;
4522 HYPRE_Real sai_loadbal;
4523 HYPRE_Int sai_reuse;
4524 HYPRE_Int sai_logging;
4527 HYPRE_ParaSailsGetNlevels(sai_precond, &sai_max_levels);
4528 HYPRE_ParaSailsGetThresh(sai_precond, &sai_threshold);
4529 HYPRE_ParaSailsGetFilter(sai_precond, &sai_filter);
4530 HYPRE_ParaSailsGetSym(sai_precond, &sai_sym);
4531 HYPRE_ParaSailsGetLoadbal(sai_precond, &sai_loadbal);
4532 HYPRE_ParaSailsGetReuse(sai_precond, &sai_reuse);
4533 HYPRE_ParaSailsGetLogging(sai_precond, &sai_logging);
4535 HYPRE_ParaSailsDestroy(sai_precond);
4536 HYPRE_ParaSailsCreate(comm, &sai_precond);
4538 HYPRE_ParaSailsSetParams(sai_precond, sai_threshold, sai_max_levels);
4539 HYPRE_ParaSailsSetFilter(sai_precond, sai_filter);
4540 HYPRE_ParaSailsSetSym(sai_precond, sai_sym);
4541 HYPRE_ParaSailsSetLoadbal(sai_precond, sai_loadbal);
4542 HYPRE_ParaSailsSetReuse(sai_precond, sai_reuse);
4543 HYPRE_ParaSailsSetLogging(sai_precond, sai_logging);
4549 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4554 HYPRE_ParCSRMatrixGetComm(*A, &comm);
4555 ResetSAIPrecond(comm);
4572 HYPRE_ParaSailsSetParams(sai_precond, threshold, max_levels);
4577 HYPRE_ParaSailsSetFilter(sai_precond, filter);
4582 HYPRE_ParaSailsSetLoadbal(sai_precond, loadbal);
4587 HYPRE_ParaSailsSetReuse(sai_precond, reuse);
4592 HYPRE_ParaSailsSetLogging(sai_precond, logging);
4597 HYPRE_ParaSailsSetSym(sai_precond, sym);
4602 HYPRE_ParaSailsDestroy(sai_precond);
4608 HYPRE_EuclidCreate(comm, &euc_precond);
4609 SetDefaultOptions();
4616 HYPRE_ParCSRMatrixGetComm(A, &comm);
4618 HYPRE_EuclidCreate(comm, &euc_precond);
4619 SetDefaultOptions();
4622 void HypreEuclid::SetDefaultOptions()
4630 HYPRE_EuclidSetLevel(euc_precond, euc_level);
4631 HYPRE_EuclidSetStats(euc_precond, euc_stats);
4632 HYPRE_EuclidSetMem(euc_precond, euc_mem);
4633 HYPRE_EuclidSetBJ(euc_precond, euc_bj);
4634 HYPRE_EuclidSetRowScale(euc_precond, euc_ro_sc);
4639 HYPRE_EuclidSetLevel(euc_precond, level);
4644 HYPRE_EuclidSetStats(euc_precond, stats);
4649 HYPRE_EuclidSetMem(euc_precond, mem);
4654 HYPRE_EuclidSetBJ(euc_precond, bj);
4659 HYPRE_EuclidSetRowScale(euc_precond, row_scale);
4662 void HypreEuclid::ResetEuclidPrecond(MPI_Comm comm)
4666 HYPRE_EuclidDestroy(euc_precond);
4667 HYPRE_EuclidCreate(comm, &euc_precond);
4669 SetDefaultOptions();
4675 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4680 HYPRE_ParCSRMatrixGetComm(*new_A, &comm);
4681 ResetEuclidPrecond(comm);
4698 HYPRE_EuclidDestroy(euc_precond);
4702 #if MFEM_HYPRE_VERSION >= 21900
4705 HYPRE_ILUCreate(&ilu_precond);
4706 SetDefaultOptions();
4709 void HypreILU::SetDefaultOptions()
4712 HYPRE_Int ilu_type = 0;
4713 HYPRE_ILUSetType(ilu_precond, ilu_type);
4716 HYPRE_Int max_iter = 1;
4717 HYPRE_ILUSetMaxIter(ilu_precond, max_iter);
4720 HYPRE_Real tol = 0.0;
4721 HYPRE_ILUSetTol(ilu_precond, tol);
4724 HYPRE_Int lev_fill = 1;
4725 HYPRE_ILUSetLevelOfFill(ilu_precond, lev_fill);
4728 HYPRE_Int reorder_type = 1;
4729 HYPRE_ILUSetLocalReordering(ilu_precond, reorder_type);
4732 HYPRE_Int print_level = 0;
4733 HYPRE_ILUSetPrintLevel(ilu_precond, print_level);
4736 void HypreILU::ResetILUPrecond()
4740 HYPRE_ILUDestroy(ilu_precond);
4742 HYPRE_ILUCreate(&ilu_precond);
4743 SetDefaultOptions();
4748 HYPRE_ILUSetLevelOfFill(ilu_precond, lev_fill);
4753 HYPRE_ILUSetType(ilu_precond, ilu_type);
4758 HYPRE_ILUSetMaxIter(ilu_precond, max_iter);
4763 HYPRE_ILUSetTol(ilu_precond, tol);
4768 HYPRE_ILUSetLocalReordering(ilu_precond, reorder_type);
4773 HYPRE_ILUSetPrintLevel(ilu_precond, print_level);
4779 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4781 if (A) { ResetILUPrecond(); }
4797 HYPRE_ILUDestroy(ilu_precond);
4804 HYPRE_BoomerAMGCreate(&amg_precond);
4805 SetDefaultOptions();
4810 HYPRE_BoomerAMGCreate(&amg_precond);
4811 SetDefaultOptions();
4814 void HypreBoomerAMG::SetDefaultOptions()
4816 #if !defined(HYPRE_USING_GPU)
4818 int coarsen_type = 10;
4820 double theta = 0.25;
4823 int interp_type = 6;
4828 int relax_sweeps = 1;
4831 int print_level = 1;
4832 int max_levels = 25;
4835 int coarsen_type = 8;
4837 double theta = 0.25;
4840 int interp_type = 6;
4844 int relax_type = 18;
4845 int relax_sweeps = 1;
4848 int print_level = 1;
4849 int max_levels = 25;
4852 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
4853 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
4854 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
4857 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
4858 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
4859 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
4860 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
4861 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
4862 HYPRE_BoomerAMGSetMaxLevels(amg_precond, max_levels);
4865 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
4866 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
4869 void HypreBoomerAMG::ResetAMGPrecond()
4871 HYPRE_Int coarsen_type;
4872 HYPRE_Int agg_levels;
4873 HYPRE_Int relax_type;
4874 HYPRE_Int relax_sweeps;
4876 HYPRE_Int interp_type;
4878 HYPRE_Int print_level;
4879 HYPRE_Int max_levels;
4881 HYPRE_Int nrbms = rbms.
Size();
4883 HYPRE_Int nodal_diag;
4884 HYPRE_Int relax_coarse;
4885 HYPRE_Int interp_vec_variant;
4887 HYPRE_Int smooth_interp_vectors;
4888 HYPRE_Int interp_refine;
4890 hypre_ParAMGData *amg_data = (hypre_ParAMGData *)amg_precond;
4893 HYPRE_BoomerAMGGetCoarsenType(amg_precond, &coarsen_type);
4894 agg_levels = hypre_ParAMGDataAggNumLevels(amg_data);
4895 relax_type = hypre_ParAMGDataUserRelaxType(amg_data);
4896 relax_sweeps = hypre_ParAMGDataUserNumSweeps(amg_data);
4897 HYPRE_BoomerAMGGetStrongThreshold(amg_precond, &theta);
4898 hypre_BoomerAMGGetInterpType(amg_precond, &interp_type);
4899 HYPRE_BoomerAMGGetPMaxElmts(amg_precond, &Pmax);
4900 HYPRE_BoomerAMGGetPrintLevel(amg_precond, &print_level);
4901 HYPRE_BoomerAMGGetMaxLevels(amg_precond, &max_levels);
4902 HYPRE_BoomerAMGGetNumFunctions(amg_precond, &dim);
4905 nodal = hypre_ParAMGDataNodal(amg_data);
4906 nodal_diag = hypre_ParAMGDataNodalDiag(amg_data);
4907 HYPRE_BoomerAMGGetCycleRelaxType(amg_precond, &relax_coarse, 3);
4908 interp_vec_variant = hypre_ParAMGInterpVecVariant(amg_data);
4909 q_max = hypre_ParAMGInterpVecQMax(amg_data);
4910 smooth_interp_vectors = hypre_ParAMGSmoothInterpVectors(amg_data);
4911 interp_refine = hypre_ParAMGInterpRefine(amg_data);
4914 HYPRE_BoomerAMGDestroy(amg_precond);
4915 HYPRE_BoomerAMGCreate(&amg_precond);
4917 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
4918 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
4919 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
4920 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
4921 HYPRE_BoomerAMGSetMaxLevels(amg_precond, max_levels);
4922 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
4923 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
4924 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
4925 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
4926 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
4927 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
4928 HYPRE_BoomerAMGSetNumFunctions(amg_precond, dim);
4931 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
4932 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
4933 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
4934 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
4935 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
4936 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
4937 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
4939 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
4946 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4948 if (A) { ResetAMGPrecond(); }
4964 HYPRE_BoomerAMGSetNumFunctions(amg_precond, dim);
4972 HYPRE_Int *h_mapping = mfem_hypre_CTAlloc_host(HYPRE_Int,
height);
4974 MFEM_VERIFY(
height % dim == 0,
"Ordering does not work as claimed!");
4976 for (
int i = 0; i <
dim; ++i)
4978 for (
int j = 0; j < h_nnodes; ++j)
4987 #if defined(hypre_IntArrayData) && defined(HYPRE_USING_GPU)
4988 HYPRE_Int *mapping = mfem_hypre_CTAlloc(HYPRE_Int,
height);
4989 hypre_TMemcpy(mapping, h_mapping, HYPRE_Int,
height,
4990 HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
4991 mfem_hypre_TFree_host(h_mapping);
4993 HYPRE_Int *mapping = h_mapping;
4998 HYPRE_BoomerAMGSetDofFunc(amg_precond, mapping);
5002 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, 0);
5003 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, 0.5);
5009 y = 0.0; y(0) = x(1); y(1) = -x(0);
5011 static void func_ryz(
const Vector &x, Vector &y)
5013 y = 0.0; y(1) = x(2); y(2) = -x(1);
5015 static void func_rzx(
const Vector &x, Vector &y)
5017 y = 0.0; y(2) = x(0); y(0) = -x(2);
5020 void HypreBoomerAMG::RecomputeRBMs()
5023 Array<HypreParVector*> gf_rbms;
5026 for (
int i = 0; i < rbms.
Size(); i++)
5028 HYPRE_ParVectorDestroy(rbms[i]);
5035 VectorFunctionCoefficient coeff_rxy(2, func_rxy);
5037 ParGridFunction rbms_rxy(fespace);
5038 rbms_rxy.ProjectCoefficient(coeff_rxy);
5041 gf_rbms.SetSize(nrbms);
5043 rbms_rxy.GetTrueDofs(*gf_rbms[0]);
5049 VectorFunctionCoefficient coeff_rxy(3, func_rxy);
5050 VectorFunctionCoefficient coeff_ryz(3, func_ryz);
5051 VectorFunctionCoefficient coeff_rzx(3, func_rzx);
5053 ParGridFunction rbms_rxy(fespace);
5054 ParGridFunction rbms_ryz(fespace);
5055 ParGridFunction rbms_rzx(fespace);
5056 rbms_rxy.ProjectCoefficient(coeff_rxy);
5057 rbms_ryz.ProjectCoefficient(coeff_ryz);
5058 rbms_rzx.ProjectCoefficient(coeff_rzx);
5061 gf_rbms.SetSize(nrbms);
5065 rbms_rxy.GetTrueDofs(*gf_rbms[0]);
5066 rbms_ryz.GetTrueDofs(*gf_rbms[1]);
5067 rbms_rzx.GetTrueDofs(*gf_rbms[2]);
5076 for (
int i = 0; i < nrbms; i++)
5078 rbms[i] = gf_rbms[i]->StealParVector();
5085 #ifdef HYPRE_USING_GPU
5086 MFEM_ABORT(
"this method is not supported in hypre built with GPU support");
5090 this->fespace = fespace_;
5100 int relax_coarse = 8;
5103 int interp_vec_variant = 2;
5105 int smooth_interp_vectors = 1;
5109 int interp_refine = 1;
5111 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
5112 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
5113 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
5114 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
5115 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
5116 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
5117 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
5120 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
5129 #if MFEM_HYPRE_VERSION >= 21800
5132 const std::string &prerelax,
5133 const std::string &postrelax)
5137 int interp_type = 100;
5138 int relax_type = 10;
5139 int coarsen_type = 6;
5140 double strength_tolC = 0.1;
5141 double strength_tolR = 0.01;
5142 double filter_tolR = 0.0;
5143 double filterA_tol = 0.0;
5146 int ns_down, ns_up, ns_coarse;
5149 ns_down = prerelax.length();
5150 ns_up = postrelax.length();
5154 HYPRE_Int **grid_relax_points = mfem_hypre_TAlloc(HYPRE_Int*, 4);
5155 grid_relax_points[0] = NULL;
5156 grid_relax_points[1] = mfem_hypre_TAlloc(HYPRE_Int, ns_down);
5157 grid_relax_points[2] = mfem_hypre_TAlloc(HYPRE_Int, ns_up);
5158 grid_relax_points[3] = mfem_hypre_TAlloc(HYPRE_Int, 1);
5159 grid_relax_points[3][0] = 0;
5162 for (
int i = 0; i<ns_down; i++)
5164 if (prerelax[i] ==
'F')
5166 grid_relax_points[1][i] = -1;
5168 else if (prerelax[i] ==
'C')
5170 grid_relax_points[1][i] = 1;
5172 else if (prerelax[i] ==
'A')
5174 grid_relax_points[1][i] = 0;
5179 for (
int i = 0; i<ns_up; i++)
5181 if (postrelax[i] ==
'F')
5183 grid_relax_points[2][i] = -1;
5185 else if (postrelax[i] ==
'C')
5187 grid_relax_points[2][i] = 1;
5189 else if (postrelax[i] ==
'A')
5191 grid_relax_points[2][i] = 0;
5195 HYPRE_BoomerAMGSetRestriction(amg_precond, distanceR);
5197 HYPRE_BoomerAMGSetGridRelaxPoints(amg_precond, grid_relax_points);
5199 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
5204 HYPRE_BoomerAMGSetSabs(amg_precond, Sabs);
5207 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
5210 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, 0);
5212 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, strength_tolC);
5216 HYPRE_BoomerAMGSetStrongThresholdR(amg_precond, strength_tolR);
5217 HYPRE_BoomerAMGSetFilterThresholdR(amg_precond, filter_tolR);
5220 if (relax_type > -1)
5222 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
5227 HYPRE_BoomerAMGSetCycleNumSweeps(amg_precond, ns_coarse, 3);
5228 HYPRE_BoomerAMGSetCycleNumSweeps(amg_precond, ns_down, 1);
5229 HYPRE_BoomerAMGSetCycleNumSweeps(amg_precond, ns_up, 2);
5231 HYPRE_BoomerAMGSetADropTol(amg_precond, filterA_tol);
5233 HYPRE_BoomerAMGSetADropType(amg_precond, -1);
5241 for (
int i = 0; i < rbms.
Size(); i++)
5243 HYPRE_ParVectorDestroy(rbms[i]);
5246 HYPRE_BoomerAMGDestroy(amg_precond);
5272 MFEM_ASSERT(G != NULL,
"");
5273 MFEM_ASSERT(x != NULL,
"");
5274 MFEM_ASSERT(y != NULL,
"");
5275 int sdim = (z == NULL) ? 2 : 3;
5276 int cycle_type = 13;
5278 MakeSolver(sdim, cycle_type);
5280 HYPRE_ParVector pz = z ?
static_cast<HYPRE_ParVector
>(*z) : NULL;
5281 HYPRE_AMSSetCoordinateVectors(ams, *x, *y, pz);
5282 HYPRE_AMSSetDiscreteGradient(ams, *G);
5285 void HypreAMS::MakeSolver(
int sdim,
int cycle_type)
5288 double rlx_weight = 1.0;
5289 double rlx_omega = 1.0;
5290 #if !defined(HYPRE_USING_GPU)
5291 int amg_coarsen_type = 10;
5292 int amg_agg_levels = 1;
5293 int amg_rlx_type = 8;
5295 double theta = 0.25;
5296 int amg_interp_type = 6;
5299 int amg_coarsen_type = 8;
5300 int amg_agg_levels = 0;
5301 int amg_rlx_type = 18;
5303 double theta = 0.25;
5304 int amg_interp_type = 6;
5309 ams_cycle_type = cycle_type;
5310 HYPRE_AMSCreate(&ams);
5312 HYPRE_AMSSetDimension(ams, sdim);
5313 HYPRE_AMSSetTol(ams, 0.0);
5314 HYPRE_AMSSetMaxIter(ams, 1);
5315 HYPRE_AMSSetCycleType(ams, cycle_type);
5316 HYPRE_AMSSetPrintLevel(ams, 1);
5319 HYPRE_AMSSetSmoothingOptions(ams, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
5320 HYPRE_AMSSetAlphaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
5321 theta, amg_interp_type, amg_Pmax);
5322 HYPRE_AMSSetBetaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
5323 theta, amg_interp_type, amg_Pmax);
5325 HYPRE_AMSSetAlphaAMGCoarseRelaxType(ams, amg_rlx_type);
5326 HYPRE_AMSSetBetaAMGCoarseRelaxType(ams, amg_rlx_type);
5335 void HypreAMS::MakeGradientAndInterpolation(
5336 ParFiniteElementSpace *edge_fespace,
int cycle_type)
5338 int dim = edge_fespace->GetMesh()->Dimension();
5339 int sdim = edge_fespace->GetMesh()->SpaceDimension();
5340 const FiniteElementCollection *edge_fec = edge_fespace->FEColl();
5342 bool trace_space, rt_trace_space;
5343 ND_Trace_FECollection *nd_tr_fec = NULL;
5344 trace_space =
dynamic_cast<const ND_Trace_FECollection*
>(edge_fec);
5345 rt_trace_space =
dynamic_cast<const RT_Trace_FECollection*
>(edge_fec);
5346 trace_space = trace_space || rt_trace_space;
5349 if (edge_fespace->GetNE() > 0)
5351 MFEM_VERIFY(!edge_fespace->IsVariableOrder(),
"");
5354 p = edge_fespace->GetFaceOrder(0);
5355 if (dim == 2) { p++; }
5359 p = edge_fespace->GetElementOrder(0);
5363 ParMesh *pmesh = edge_fespace->GetParMesh();
5366 nd_tr_fec =
new ND_Trace_FECollection(p, dim);
5367 edge_fespace =
new ParFiniteElementSpace(pmesh, nd_tr_fec);
5371 FiniteElementCollection *vert_fec;
5374 vert_fec =
new H1_Trace_FECollection(p, dim);
5378 vert_fec =
new H1_FECollection(p, dim);
5380 ParFiniteElementSpace *vert_fespace =
new ParFiniteElementSpace(pmesh,
5384 if (p == 1 && pmesh->GetNodes() == NULL)
5386 ParGridFunction x_coord(vert_fespace);
5387 ParGridFunction y_coord(vert_fespace);
5388 ParGridFunction z_coord(vert_fespace);
5390 for (
int i = 0; i < pmesh->GetNV(); i++)
5392 coord = pmesh -> GetVertex(i);
5393 x_coord(i) = coord[0];
5394 if (sdim >= 2) { y_coord(i) = coord[1]; }
5395 if (sdim == 3) { z_coord(i) = coord[2]; }
5397 x = x_coord.ParallelProject();
5404 y = y_coord.ParallelProject();
5409 z = z_coord.ParallelProject();
5413 HYPRE_AMSSetCoordinateVectors(ams,
5414 x ? (HYPRE_ParVector)(*x) : NULL,
5415 y ? (HYPRE_ParVector)(*y) : NULL,
5416 z ? (HYPRE_ParVector)(*z) : NULL);
5426 ParDiscreteLinearOperator *grad;
5427 grad =
new ParDiscreteLinearOperator(vert_fespace, edge_fespace);
5430 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
5434 grad->AddDomainInterpolator(
new GradientInterpolator);
5438 G = grad->ParallelAssemble();
5439 HYPRE_AMSSetDiscreteGradient(ams, *G);
5443 Pi = Pix = Piy = Piz = NULL;
5444 if (p > 1 || pmesh->GetNodes() != NULL)
5446 ParFiniteElementSpace *vert_fespace_d
5449 ParDiscreteLinearOperator *id_ND;
5450 id_ND =
new ParDiscreteLinearOperator(vert_fespace_d, edge_fespace);
5453 id_ND->AddTraceFaceInterpolator(
new IdentityInterpolator);
5457 id_ND->AddDomainInterpolator(
new IdentityInterpolator);
5462 if (cycle_type < 10)
5464 Pi = id_ND->ParallelAssemble();
5468 Array2D<HypreParMatrix *> Pi_blocks;
5469 id_ND->GetParBlocks(Pi_blocks);
5470 Pix = Pi_blocks(0,0);
5471 if (sdim >= 2) { Piy = Pi_blocks(0,1); }
5472 if (sdim == 3) { Piz = Pi_blocks(0,2); }
5477 HYPRE_ParCSRMatrix HY_Pi = (Pi) ? (HYPRE_ParCSRMatrix) *Pi : NULL;
5478 HYPRE_ParCSRMatrix HY_Pix = (Pix) ? (HYPRE_ParCSRMatrix) *Pix : NULL;
5479 HYPRE_ParCSRMatrix HY_Piy = (Piy) ? (HYPRE_ParCSRMatrix) *Piy : NULL;
5480 HYPRE_ParCSRMatrix HY_Piz = (Piz) ? (HYPRE_ParCSRMatrix) *Piz : NULL;
5481 HYPRE_AMSSetInterpolations(ams, HY_Pi, HY_Pix, HY_Piy, HY_Piz);
5483 delete vert_fespace_d;
5486 delete vert_fespace;
5491 delete edge_fespace;
5496 void HypreAMS::Init(ParFiniteElementSpace *edge_fespace)
5498 int cycle_type = 13;
5499 int sdim = edge_fespace->GetMesh()->SpaceDimension();
5500 MakeSolver(sdim, cycle_type);
5501 MakeGradientAndInterpolation(edge_fespace, cycle_type);
5504 void HypreAMS::ResetAMSPrecond()
5506 #if MFEM_HYPRE_VERSION >= 22600
5508 auto *ams_data = (hypre_AMSData *)ams;
5511 HYPRE_Int dim = hypre_AMSDataDimension(ams_data);
5514 hypre_ParCSRMatrix *hy_G = hypre_AMSDataDiscreteGradient(ams_data);
5516 HYPRE_Int beta_is_zero = hypre_AMSDataBetaIsZero(ams_data);
5519 hypre_ParCSRMatrix *hy_Pi hypre_AMSDataPiInterpolation(ams_data);
5520 hypre_ParCSRMatrix *hy_Pix = ams_data->Pix;
5521 hypre_ParCSRMatrix *hy_Piy = ams_data->Piy;
5522 hypre_ParCSRMatrix *hy_Piz = ams_data->Piz;
5523 HYPRE_Int owns_Pi = hypre_AMSDataOwnsPiInterpolation(ams_data);
5526 ams_data->owns_Pi = 0;
5530 hypre_ParVector *hy_x = hypre_AMSDataVertexCoordinateX(ams_data);
5531 hypre_ParVector *hy_y = hypre_AMSDataVertexCoordinateY(ams_data);
5532 hypre_ParVector *hy_z = hypre_AMSDataVertexCoordinateZ(ams_data);
5535 HYPRE_Int maxit = hypre_AMSDataMaxIter(ams_data);
5536 HYPRE_Real tol = hypre_AMSDataTol(ams_data);
5537 HYPRE_Int cycle_type = hypre_AMSDataCycleType(ams_data);
5538 HYPRE_Int ams_print_level = hypre_AMSDataPrintLevel(ams_data);
5541 HYPRE_Int A_relax_type = hypre_AMSDataARelaxType(ams_data);
5542 HYPRE_Int A_relax_times = hypre_AMSDataARelaxTimes(ams_data);
5543 HYPRE_Real A_relax_weight = hypre_AMSDataARelaxWeight(ams_data);
5544 HYPRE_Real A_omega = hypre_AMSDataAOmega(ams_data);
5545 HYPRE_Int A_cheby_order = hypre_AMSDataAChebyOrder(ams_data);
5546 HYPRE_Real A_cheby_fraction = hypre_AMSDataAChebyFraction(ams_data);
5548 HYPRE_Int B_Pi_coarsen_type = hypre_AMSDataPoissonAlphaAMGCoarsenType(ams_data);
5549 HYPRE_Int B_Pi_agg_levels = hypre_AMSDataPoissonAlphaAMGAggLevels(ams_data);
5550 HYPRE_Int B_Pi_relax_type = hypre_AMSDataPoissonAlphaAMGRelaxType(ams_data);
5551 HYPRE_Int B_Pi_coarse_relax_type = ams_data->B_Pi_coarse_relax_type;
5552 HYPRE_Real B_Pi_theta = hypre_AMSDataPoissonAlphaAMGStrengthThreshold(ams_data);
5553 HYPRE_Int B_Pi_interp_type = ams_data->B_Pi_interp_type;
5554 HYPRE_Int B_Pi_Pmax = ams_data->B_Pi_Pmax;
5556 HYPRE_Int B_G_coarsen_type = hypre_AMSDataPoissonBetaAMGCoarsenType(ams_data);
5557 HYPRE_Int B_G_agg_levels = hypre_AMSDataPoissonBetaAMGAggLevels(ams_data);
5558 HYPRE_Int B_G_relax_type = hypre_AMSDataPoissonBetaAMGRelaxType(ams_data);
5559 HYPRE_Int B_G_coarse_relax_type = ams_data->B_G_coarse_relax_type;
5560 HYPRE_Real B_G_theta = hypre_AMSDataPoissonBetaAMGStrengthThreshold(ams_data);
5561 HYPRE_Int B_G_interp_type = ams_data->B_G_interp_type;
5562 HYPRE_Int B_G_Pmax = ams_data->B_G_Pmax;
5564 HYPRE_AMSDestroy(ams);
5565 HYPRE_AMSCreate(&ams);
5566 ams_data = (hypre_AMSData *)ams;
5568 HYPRE_AMSSetDimension(ams, dim);
5569 HYPRE_AMSSetTol(ams, tol);
5570 HYPRE_AMSSetMaxIter(ams, maxit);
5571 HYPRE_AMSSetCycleType(ams, cycle_type);
5572 HYPRE_AMSSetPrintLevel(ams, ams_print_level);
5574 HYPRE_AMSSetCoordinateVectors(ams, hy_x, hy_y, hy_z);
5576 HYPRE_AMSSetDiscreteGradient(ams, hy_G);
5577 HYPRE_AMSSetCoordinateVectors(ams, hy_x, hy_y, hy_z);
5578 HYPRE_AMSSetInterpolations(ams, hy_Pi, hy_Pix, hy_Piy, hy_Piz);
5579 ams_data->owns_Pi = owns_Pi;
5582 HYPRE_AMSSetSmoothingOptions(ams, A_relax_type, A_relax_times, A_relax_weight,
5585 hypre_AMSDataAChebyOrder(ams_data) = A_cheby_order;
5586 hypre_AMSDataAChebyFraction(ams_data) = A_cheby_fraction;
5588 HYPRE_AMSSetAlphaAMGOptions(ams, B_Pi_coarsen_type, B_Pi_agg_levels,
5590 B_Pi_theta, B_Pi_interp_type, B_Pi_Pmax);
5591 HYPRE_AMSSetBetaAMGOptions(ams, B_G_coarsen_type, B_G_agg_levels,
5593 B_G_theta, B_G_interp_type, B_G_Pmax);
5595 HYPRE_AMSSetAlphaAMGCoarseRelaxType(ams, B_Pi_coarse_relax_type);
5596 HYPRE_AMSSetBetaAMGCoarseRelaxType(ams, B_G_coarse_relax_type);
5598 ams_data->beta_is_zero = beta_is_zero;
5601 HYPRE_AMSDestroy(ams);
5603 MakeSolver(space_dim, ams_cycle_type);
5605 HYPRE_AMSSetPrintLevel(ams, print_level);
5606 if (singular) { HYPRE_AMSSetBetaPoissonMatrix(ams, NULL); }
5608 HYPRE_AMSSetDiscreteGradient(ams, *G);
5611 HYPRE_AMSSetCoordinateVectors(ams,
5612 x ? (HYPRE_ParVector)(*x) :
nullptr,
5613 y ? (HYPRE_ParVector)(*y) :
nullptr,
5614 z ? (HYPRE_ParVector)(*z) :
nullptr);
5618 HYPRE_AMSSetInterpolations(ams,
5619 Pi ? (HYPRE_ParCSRMatrix) *Pi :
nullptr,
5620 Pix ? (HYPRE_ParCSRMatrix) *Pix :
nullptr,
5621 Piy ? (HYPRE_ParCSRMatrix) *Piy :
nullptr,
5622 Piz ? (HYPRE_ParCSRMatrix) *Piz :
nullptr);
5630 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
5632 if (A) { ResetAMSPrecond(); }
5649 HYPRE_AMSDestroy(ams);
5664 HYPRE_AMSSetPrintLevel(ams, print_lvl);
5665 print_level = print_lvl;
5683 x(x_), y(y_), z(z_),
5685 ND_Pi(NULL), ND_Pix(NULL), ND_Piy(NULL), ND_Piz(NULL),
5686 RT_Pi(NULL), RT_Pix(NULL), RT_Piy(NULL), RT_Piz(NULL)
5688 MFEM_ASSERT(C != NULL,
"");
5689 MFEM_ASSERT(G != NULL,
"");
5690 MFEM_ASSERT(x != NULL,
"");
5691 MFEM_ASSERT(y != NULL,
"");
5692 MFEM_ASSERT(z != NULL,
"");
5696 HYPRE_ADSSetCoordinateVectors(ads, *x, *y, *z);
5697 HYPRE_ADSSetDiscreteCurl(ads, *C);
5698 HYPRE_ADSSetDiscreteGradient(ads, *G);
5701 void HypreADS::MakeSolver()
5704 double rlx_weight = 1.0;
5705 double rlx_omega = 1.0;
5706 #if !defined(HYPRE_USING_GPU)
5708 int amg_coarsen_type = 10;
5709 int amg_agg_levels = 1;
5710 int amg_rlx_type = 8;
5711 double theta = 0.25;
5712 int amg_interp_type = 6;
5716 int amg_coarsen_type = 8;
5717 int amg_agg_levels = 0;
5718 int amg_rlx_type = 18;
5719 double theta = 0.25;
5720 int amg_interp_type = 6;
5724 HYPRE_ADSCreate(&ads);
5726 HYPRE_ADSSetTol(ads, 0.0);
5727 HYPRE_ADSSetMaxIter(ads, 1);
5728 HYPRE_ADSSetCycleType(ads, cycle_type);
5729 HYPRE_ADSSetPrintLevel(ads, 1);
5732 HYPRE_ADSSetSmoothingOptions(ads, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
5733 HYPRE_ADSSetAMGOptions(ads, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
5734 theta, amg_interp_type, amg_Pmax);
5735 HYPRE_ADSSetAMSOptions(ads, ams_cycle_type, amg_coarsen_type, amg_agg_levels,
5736 amg_rlx_type, theta, amg_interp_type, amg_Pmax);
5745 void HypreADS::MakeDiscreteMatrices(ParFiniteElementSpace *face_fespace)
5747 const FiniteElementCollection *face_fec = face_fespace->FEColl();
5749 (
dynamic_cast<const RT_Trace_FECollection*
>(face_fec) != NULL);
5751 if (face_fespace->GetNE() > 0)
5753 MFEM_VERIFY(!face_fespace->IsVariableOrder(),
"");
5756 p = face_fespace->GetFaceOrder(0) + 1;
5760 p = face_fespace->GetElementOrder(0);
5765 ParMesh *pmesh = (ParMesh *) face_fespace->GetMesh();
5766 FiniteElementCollection *vert_fec, *edge_fec;
5769 vert_fec =
new H1_Trace_FECollection(p, 3);
5770 edge_fec =
new ND_Trace_FECollection(p, 3);
5774 vert_fec =
new H1_FECollection(p, 3);
5775 edge_fec =
new ND_FECollection(p, 3);
5778 ParFiniteElementSpace *vert_fespace =
new ParFiniteElementSpace(pmesh,
5780 ParFiniteElementSpace *edge_fespace =
new ParFiniteElementSpace(pmesh,
5784 if (p == 1 && pmesh->GetNodes() == NULL)
5786 ParGridFunction x_coord(vert_fespace);
5787 ParGridFunction y_coord(vert_fespace);
5788 ParGridFunction z_coord(vert_fespace);
5790 for (
int i = 0; i < pmesh->GetNV(); i++)
5792 coord = pmesh -> GetVertex(i);
5793 x_coord(i) = coord[0];
5794 y_coord(i) = coord[1];
5795 z_coord(i) = coord[2];
5797 x = x_coord.ParallelProject();
5798 y = y_coord.ParallelProject();
5799 z = z_coord.ParallelProject();
5803 HYPRE_ADSSetCoordinateVectors(ads, *x, *y, *z);
5813 ParDiscreteLinearOperator *curl;
5814 curl =
new ParDiscreteLinearOperator(edge_fespace, face_fespace);
5817 curl->AddTraceFaceInterpolator(
new CurlInterpolator);
5821 curl->AddDomainInterpolator(
new CurlInterpolator);
5825 C = curl->ParallelAssemble();
5827 HYPRE_ADSSetDiscreteCurl(ads, *C);
5831 ParDiscreteLinearOperator *grad;
5832 grad =
new ParDiscreteLinearOperator(vert_fespace, edge_fespace);
5835 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
5839 grad->AddDomainInterpolator(
new GradientInterpolator);
5843 G = grad->ParallelAssemble();
5846 HYPRE_ADSSetDiscreteGradient(ads, *G);
5850 RT_Pi = RT_Pix = RT_Piy = RT_Piz = NULL;
5851 ND_Pi = ND_Pix = ND_Piy = ND_Piz = NULL;
5852 if (p > 1 || pmesh->GetNodes() != NULL)
5854 ParFiniteElementSpace *vert_fespace_d
5857 ParDiscreteLinearOperator *id_ND;
5858 id_ND =
new ParDiscreteLinearOperator(vert_fespace_d, edge_fespace);
5861 id_ND->AddTraceFaceInterpolator(
new IdentityInterpolator);
5865 id_ND->AddDomainInterpolator(
new IdentityInterpolator);
5870 if (ams_cycle_type < 10)
5872 ND_Pi = id_ND->ParallelAssemble();
5878 Array2D<HypreParMatrix *> ND_Pi_blocks;
5879 id_ND->GetParBlocks(ND_Pi_blocks);
5880 ND_Pix = ND_Pi_blocks(0,0);
5881 ND_Piy = ND_Pi_blocks(0,1);
5882 ND_Piz = ND_Pi_blocks(0,2);
5887 ParDiscreteLinearOperator *id_RT;
5888 id_RT =
new ParDiscreteLinearOperator(vert_fespace_d, face_fespace);
5891 id_RT->AddTraceFaceInterpolator(
new NormalInterpolator);
5895 id_RT->AddDomainInterpolator(
new IdentityInterpolator);
5900 if (cycle_type < 10)
5902 RT_Pi = id_RT->ParallelAssemble();
5907 Array2D<HypreParMatrix *> RT_Pi_blocks;
5908 id_RT->GetParBlocks(RT_Pi_blocks);
5909 RT_Pix = RT_Pi_blocks(0,0);
5910 RT_Piy = RT_Pi_blocks(0,1);
5911 RT_Piz = RT_Pi_blocks(0,2);
5916 HYPRE_ParCSRMatrix HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz;
5917 HY_RT_Pi = (RT_Pi) ? (HYPRE_ParCSRMatrix) *RT_Pi : NULL;
5918 HY_RT_Pix = (RT_Pix) ? (HYPRE_ParCSRMatrix) *RT_Pix : NULL;
5919 HY_RT_Piy = (RT_Piy) ? (HYPRE_ParCSRMatrix) *RT_Piy : NULL;
5920 HY_RT_Piz = (RT_Piz) ? (HYPRE_ParCSRMatrix) *RT_Piz : NULL;
5921 HYPRE_ParCSRMatrix HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz;
5922 HY_ND_Pi = (ND_Pi) ? (HYPRE_ParCSRMatrix) *ND_Pi : NULL;
5923 HY_ND_Pix = (ND_Pix) ? (HYPRE_ParCSRMatrix) *ND_Pix : NULL;
5924 HY_ND_Piy = (ND_Piy) ? (HYPRE_ParCSRMatrix) *ND_Piy : NULL;
5925 HY_ND_Piz = (ND_Piz) ? (HYPRE_ParCSRMatrix) *ND_Piz : NULL;
5926 HYPRE_ADSSetInterpolations(ads,
5927 HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz,
5928 HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz);
5930 delete vert_fespace_d;
5934 delete vert_fespace;
5936 delete edge_fespace;
5939 void HypreADS::Init(ParFiniteElementSpace *face_fespace)
5942 MakeDiscreteMatrices(face_fespace);
5945 void HypreADS::ResetADSPrecond()
5947 HYPRE_ADSDestroy(ads);
5951 HYPRE_ADSSetPrintLevel(ads, print_level);
5953 HYPRE_ADSSetDiscreteCurl(ads, *C);
5954 HYPRE_ADSSetDiscreteGradient(ads, *G);
5957 MFEM_VERIFY(x && y && z,
"");
5958 HYPRE_ADSSetCoordinateVectors(ads, *x, *y, *z);
5962 HYPRE_ParCSRMatrix HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz;
5963 HY_RT_Pi = (RT_Pi) ? (HYPRE_ParCSRMatrix) *RT_Pi : NULL;
5964 HY_RT_Pix = (RT_Pix) ? (HYPRE_ParCSRMatrix) *RT_Pix : NULL;
5965 HY_RT_Piy = (RT_Piy) ? (HYPRE_ParCSRMatrix) *RT_Piy : NULL;
5966 HY_RT_Piz = (RT_Piz) ? (HYPRE_ParCSRMatrix) *RT_Piz : NULL;
5967 HYPRE_ParCSRMatrix HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz;
5968 HY_ND_Pi = (ND_Pi) ? (HYPRE_ParCSRMatrix) *ND_Pi : NULL;
5969 HY_ND_Pix = (ND_Pix) ? (HYPRE_ParCSRMatrix) *ND_Pix : NULL;
5970 HY_ND_Piy = (ND_Piy) ? (HYPRE_ParCSRMatrix) *ND_Piy : NULL;
5971 HY_ND_Piz = (ND_Piz) ? (HYPRE_ParCSRMatrix) *ND_Piz : NULL;
5972 HYPRE_ADSSetInterpolations(ads,
5973 HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz,
5974 HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz);
5981 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
5983 if (A) { ResetADSPrecond(); }
6000 HYPRE_ADSDestroy(ads);
6022 HYPRE_ADSSetPrintLevel(ads, print_lvl);
6023 print_level = print_lvl;
6026 HypreLOBPCG::HypreMultiVector::HypreMultiVector(
int n,
HypreParVector & v,
6027 mv_InterfaceInterpreter & interpreter)
6031 mv_ptr = mv_MultiVectorCreateFromSampleVector(&interpreter, nv,
6032 (HYPRE_ParVector)v);
6034 HYPRE_ParVector* vecs = NULL;
6036 mv_TempMultiVector* tmp =
6037 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
6038 vecs = (HYPRE_ParVector*)(tmp -> vector);
6041 hpv =
new HypreParVector*[nv];
6042 for (
int i=0; i<nv; i++)
6044 hpv[i] =
new HypreParVector(vecs[i]);
6048 HypreLOBPCG::HypreMultiVector::~HypreMultiVector()
6052 for (
int i=0; i<nv; i++)
6059 mv_MultiVectorDestroy(mv_ptr);
6063 HypreLOBPCG::HypreMultiVector::Randomize(HYPRE_Int seed_)
6065 mv_MultiVectorSetRandom(mv_ptr, seed_);
6069 HypreLOBPCG::HypreMultiVector::GetVector(
unsigned int i)
6071 MFEM_ASSERT((
int)i < nv,
"index out of range");
6077 HypreLOBPCG::HypreMultiVector::StealVectors()
6079 HypreParVector ** hpv_ret = hpv;
6083 mv_TempMultiVector * mv_tmp =
6084 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
6086 mv_tmp->ownsVectors = 0;
6088 for (
int i=0; i<nv; i++)
6090 hpv_ret[i]->SetOwnership(1);
6108 MPI_Comm_size(comm,&numProcs);
6109 MPI_Comm_rank(comm,&myid);
6111 HYPRE_ParCSRSetupInterpreter(&interpreter);
6112 HYPRE_ParCSRSetupMatvec(&matvec_fn);
6113 HYPRE_LOBPCGCreate(&interpreter, &matvec_fn, &lobpcg_solver);
6122 HYPRE_LOBPCGDestroy(lobpcg_solver);
6128 HYPRE_LOBPCGSetTol(lobpcg_solver, tol);
6134 #if MFEM_HYPRE_VERSION >= 21101
6135 HYPRE_LOBPCGSetRTol(lobpcg_solver, rel_tol);
6137 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
6144 HYPRE_LOBPCGSetMaxIter(lobpcg_solver, max_iter);
6152 HYPRE_LOBPCGSetPrintLevel(lobpcg_solver, logging);
6159 HYPRE_LOBPCGSetPrecondUsageMode(lobpcg_solver, pcg_mode);
6165 HYPRE_LOBPCGSetPrecond(lobpcg_solver,
6166 (HYPRE_PtrToSolverFcn)this->PrecondSolve,
6167 (HYPRE_PtrToSolverFcn)this->PrecondSetup,
6168 (HYPRE_Solver)&precond);
6176 if (HYPRE_AssumedPartitionCheck())
6180 MPI_Scan(&locSize, &part[1], 1, HYPRE_MPI_BIG_INT, MPI_SUM, comm);
6182 part[0] = part[1] - locSize;
6184 MPI_Allreduce(&locSize, &glbSize, 1, HYPRE_MPI_BIG_INT, MPI_SUM, comm);
6190 MPI_Allgather(&locSize, 1, HYPRE_MPI_BIG_INT,
6191 &part[1], 1, HYPRE_MPI_BIG_INT, comm);
6194 for (
int i=0; i<numProcs; i++)
6196 part[i+1] += part[i];
6199 glbSize = part[numProcs];
6208 const bool is_device_ptr =
true;
6211 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
6212 matvec_fn.Matvec = this->OperatorMatvec;
6213 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
6215 HYPRE_LOBPCGSetup(lobpcg_solver,(HYPRE_Matrix)&A,NULL,NULL);
6221 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
6222 matvec_fn.Matvec = this->OperatorMatvec;
6223 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
6225 HYPRE_LOBPCGSetupB(lobpcg_solver,(HYPRE_Matrix)&M,NULL);
6234 for (
int i=0; i<nev; i++)
6236 eigs[i] = eigenvalues[i];
6243 return multi_vec->GetVector(i);
6250 if ( multi_vec == NULL )
6252 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::SetInitialVectors()");
6254 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
6258 for (
int i=0; i < min(num_vecs,nev); i++)
6260 multi_vec->GetVector(i) = *vecs[i];
6264 for (
int i=min(num_vecs,nev); i < nev; i++)
6266 multi_vec->GetVector(i).Randomize(seed);
6270 if ( subSpaceProj != NULL )
6273 y = multi_vec->GetVector(0);
6275 for (
int i=1; i<nev; i++)
6277 subSpaceProj->
Mult(multi_vec->GetVector(i),
6278 multi_vec->GetVector(i-1));
6280 subSpaceProj->
Mult(y,
6281 multi_vec->GetVector(nev-1));
6289 if ( multi_vec == NULL )
6291 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::Solve()");
6293 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
6294 multi_vec->Randomize(seed);
6296 if ( subSpaceProj != NULL )
6299 y = multi_vec->GetVector(0);
6301 for (
int i=1; i<nev; i++)
6303 subSpaceProj->
Mult(multi_vec->GetVector(i),
6304 multi_vec->GetVector(i-1));
6306 subSpaceProj->
Mult(y, multi_vec->GetVector(nev-1));
6317 HYPRE_LOBPCGSolve(lobpcg_solver, NULL, *multi_vec, eigenvalues);
6321 HypreLOBPCG::OperatorMatvecCreate(
void *A,
6328 return ( matvec_data );
6332 HypreLOBPCG::OperatorMatvec(
void *matvec_data,
6333 HYPRE_Complex alpha,
6339 MFEM_VERIFY(alpha == 1.0 && beta == 0.0,
"values not supported");
6341 Operator *Aop = (Operator*)A;
6343 hypre_ParVector * xPar = (hypre_ParVector *)x;
6344 hypre_ParVector * yPar = (hypre_ParVector *)y;
6346 HypreParVector xVec(xPar);
6347 HypreParVector yVec(yPar);
6349 Aop->Mult( xVec, yVec );
6353 yVec.HypreReadWrite();
6359 HypreLOBPCG::OperatorMatvecDestroy(
void *matvec_data )
6365 HypreLOBPCG::PrecondSolve(
void *solver,
6370 Solver *
PC = (Solver*)solver;
6372 hypre_ParVector * bPar = (hypre_ParVector *)b;
6373 hypre_ParVector * xPar = (hypre_ParVector *)x;
6375 HypreParVector bVec(bPar);
6376 HypreParVector xVec(xPar);
6378 PC->Mult( bVec, xVec );
6382 xVec.HypreReadWrite();
6388 HypreLOBPCG::PrecondSetup(
void *solver,
6406 MPI_Comm_size(comm,&numProcs);
6407 MPI_Comm_rank(comm,&myid);
6409 HYPRE_AMECreate(&ame_solver);
6410 HYPRE_AMESetPrintLevel(ame_solver, 0);
6417 mfem_hypre_TFree_host(multi_vec);
6422 for (
int i=0; i<nev; i++)
6424 delete eigenvectors[i];
6427 delete [] eigenvectors;
6431 mfem_hypre_TFree_host(eigenvalues);
6434 HYPRE_AMEDestroy(ame_solver);
6442 HYPRE_AMESetBlockSize(ame_solver, nev);
6448 HYPRE_AMESetTol(ame_solver, tol);
6454 #if MFEM_HYPRE_VERSION >= 21101
6455 HYPRE_AMESetRTol(ame_solver, rel_tol);
6457 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
6464 HYPRE_AMESetMaxIter(ame_solver, max_iter);
6472 HYPRE_AMESetPrintLevel(ame_solver, logging);
6479 ams_precond = &precond;
6487 HYPRE_Solver ams_precond_ptr = (HYPRE_Solver)*ams_precond;
6489 ams_precond->
SetupFcn()(*ams_precond,A,NULL,NULL);
6491 HYPRE_AMESetAMSSolver(ame_solver, ams_precond_ptr);
6494 HYPRE_AMESetup(ame_solver);
6500 HYPRE_ParCSRMatrix parcsr_M = M;
6501 HYPRE_AMESetMassMatrix(ame_solver,(HYPRE_ParCSRMatrix)parcsr_M);
6507 HYPRE_AMESolve(ame_solver);
6510 HYPRE_AMEGetEigenvalues(ame_solver,&eigenvalues);
6513 HYPRE_AMEGetEigenvectors(ame_solver,&multi_vec);
6520 eigs.
SetSize(nev); eigs = -1.0;
6523 for (
int i=0; i<nev; i++)
6525 eigs[i] = eigenvalues[i];
6530 HypreAME::createDummyVectors()
const
6533 for (
int i=0; i<nev; i++)
6540 const HypreParVector &
6543 if ( eigenvectors == NULL )
6545 this->createDummyVectors();
6548 return *eigenvectors[i];
6554 if ( eigenvectors == NULL )
6556 this->createDummyVectors();
6561 eigenvectors = NULL;
MemoryType GetHypreMemoryType()
The MemoryType used by MFEM when allocating arrays for Hypre objects.
virtual ~HypreBoomerAMG()
void SetAbsTol(double atol)
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)
int Size() const
Return the logical size of the array.
void EliminateRowsCols(const Array< int > &rows_cols, const HypreParVector &X, HypreParVector &B)
HypreADS(ParFiniteElementSpace *face_fespace)
virtual int NumNonZeroElems() const
Returns the number of the nonzero elements in the matrix.
static constexpr Type default_type
MPI_Comm GetComm() const
MPI communicator.
HypreEuclid(MPI_Comm comm)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Vector * GlobalVector() const
Returns the global vector in each processor.
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.
void MakeDataOwner() const
Set the Vector data (host pointer) ownership flag.
static MemoryClass GetHostMemoryClass()
Get the current Host MemoryClass. This is the MemoryClass used by most MFEM host Memory objects...
void SetPrintLevel(int print_lvl)
ParMesh * GetParMesh() const
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 HypreRead() const
Prepare the HypreParVector for read access in hypre's device memory space, HYPRE_MEMORY_DEVICE.
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.
void HypreRead() const
Update the internal hypre_ParCSRMatrix object, A, to be in hypre memory space.
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.
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 CreateCompatibleVector() const
Constructs a HypreParVector compatible with the calling vector.
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.
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void SetInitialVectors(int num_vecs, HypreParVector **vecs)
double Norml2() const
Returns the l2 norm of the vector.
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.
bool WrapVectors(const Vector &b, Vector &x) const
Makes the internal HypreParVectors B and X wrap the input vectors b and x.
HYPRE_BigInt GlobalTrueVSize() const
T * GetData()
Returns the data.
Issue warnings on hypre errors.
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...
void SetPreconditioner(HypreSolver &precond)
virtual double * HostWrite()
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
int Size() const
Returns the size of the vector.
void SetDevicePtrOwner(bool own) const
Set/clear the ownership flag for the device pointer. Ownership indicates whether the pointer will be ...
HypreILU()
Constructor; sets the default options.
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.
void SetPrintLevel(int print_lvl)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
std::string GetHash() const
Return the hash string for the current sequence and reset (clear) the sequence.
void SetPreconditioner(Solver &precond)
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.
double Normlinf() const
Returns the l_infinity norm of the vector.
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 SetAdvectiveOptions(int distance=15, const std::string &prerelax="", const std::string &postrelax="FFC")
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.
bool pos_l1_norms
If set, take absolute values of the computed l1_norms.
double * GetData() const
Return a pointer to the beginning of the Vector data.
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B, bool own_matrix)
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)
int Size_of_connections() const
double poly_fraction
Fraction of spectrum to smooth for polynomial relaxation.
Memory< double > & GetMemoryData()
int Capacity() const
Return the size of the allocated memory.
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 GetEigenvalues(Array< double > &eigenvalues) const
Collect the converged eigenvalues.
void SetMaxIter(HYPRE_Int max_iter)
HypreFGMRES(MPI_Comm comm)
HYPRE_BigInt N() const
Returns the global number of columns.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's FGMRES.
HYPRE_BigInt M() const
Returns the global number of rows.
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)
void GetOffd(SparseMatrix &offd, HYPRE_BigInt *&cmap) const
Get the local off-diagonal block. NOTE: 'offd' will not own any data.
Vector & operator=(const double *v)
Copy Size() entries from v.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's GMRES.
void Print(const char *fname) const
Prints the locally owned rows in parallel.
bool MemoryClassContainsType(MemoryClass mc, MemoryType mt)
Return true iff the MemoryType mt is contained in the MemoryClass mc.
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...
HypreLOBPCG(MPI_Comm comm)
HYPRE_BigInt * GetRowStarts() const
Return the parallel row partitioning array.
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Relax the linear system Ax=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 SetMaxIter(int max_iter)
double * l1_norms
l1 norms of the rows of A
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void SetOwnerFlags(signed char diag, signed char offd, signed char colmap)
Explicitly set the three ownership flags, see docs for diagOwner etc.
void PrintHash(std::ostream &out) const
Print sizes and hashes for all data arrays of the HypreParMatrix from the local MPI rank...
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 ResetTranspose() const
Reset (destroy) the internal transpose matrix that is created by EnsureMultTranspose() and MultTransp...
void GetBlocks(Array2D< HypreParMatrix * > &blocks, bool interleaved_rows=false, bool interleaved_cols=false) const
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve the linear system Ax=b.
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 Read(MPI_Comm comm, const char *fname)
Reads a HypreParVector from files saved with HypreParVector::Print.
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.
bool OwnsHostPtr() const
Return true if the host pointer is owned. Ownership indicates whether the pointer will be deleted by ...
HypreParMatrix * Transpose() const
Returns the transpose of *this.
HYPRE_Int Randomize(HYPRE_Int seed)
Set random values.
Ignore hypre errors (see e.g. HypreADS)
double relax_weight
Damping coefficient (usually <= 1)
void SetElasticityOptions(ParFiniteElementSpace *fespace)
void GetDiag(Vector &diag) const
Get the local diagonal of the matrix.
void Sort()
Sorts the array in ascending order. This requires operator< to be defined for T.
int Size() const
Returns the number of TYPE I elements.
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...
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.
virtual const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
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)
HYPRE_BigInt GetGlobalNumCols() const
Return the global number of columns.
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 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.
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)
double Norml1() const
Returns the l_1 norm of the vector.
int ParCSRRelax_Taubin(hypre_ParCSRMatrix *A, hypre_ParVector *f, double lambda, double mu, int N, double max_eig, hypre_ParVector *u, hypre_ParVector *r)
HYPRE_BigInt * GetTrueDofOffsets() const
void ClearOwnerFlags() const
Clear the ownership flags for the host and device pointers, as well as any internal data allocated by...
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...
MemoryType GetDeviceMemoryType() const
Return the device MemoryType of the Memory object. If the device MemoryType is not set...
signed char OwnsOffd() const
Get offd ownership flag.
int NumRows() const
Get the number of rows (size of output) of the Operator. Synonym with Height().
void HostRead() const
Update the internal hypre_ParCSRMatrix object, A, to be on host.
MemoryType
Memory types supported by MFEM.
signed char OwnsColMap() const
Get colmap ownership flag.
void SetPrintLevel(int print_lvl)
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_.
int NumCols() const
Get the number of columns (size of input) of the Operator. Synonym with Width().
void SetNumModes(int num_eigs)
const HypreParVector & GetEigenvector(unsigned int i) const
Extract a single eigenvector.
int GetNumRows() const
Returns the number of rows in the diagonal block of the ParCSRMatrix.
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.
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.
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 MakeAlias(const Memory &base, int offset, int size)
Create a memory object that points inside the memory object base.
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 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 Print(const char *fname, HYPRE_Int offi=0, HYPRE_Int offj=0) const
Prints the locally owned rows in parallel.
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.
HYPRE_BigInt GetGlobalNumRows() const
Return the global number of rows.
void EnsureMultTranspose() const
Ensure the action of the transpose is performed fast.
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)
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 SetTaubinOptions(double lambda, double mu, int iter)
Set parameters for Taubin's lambda-mu method.
bool Empty() const
Return true if the Memory object is empty, see Reset().
HypreParVector * B
Right-hand side and solution vectors.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
virtual void MultTranspose(const Vector &b, Vector &x) const
Apply transpose of the smoother to relax the linear system Ax=b.
A simple singleton class for hypre's global settings, that 1) calls HYPRE_Init() and sets some GPU-re...
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.
int GetNumCols() const
Returns the number of columns in the diagonal block of the ParCSRMatrix.
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)
int relax_times
Number of relaxation sweeps.
void GetEigenvalues(Array< double > &eigenvalues) const
Collect the converged eigenvalues.
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.
Abstract class for hypre's solvers and preconditioners.
ErrorMode error_mode
How to treat hypre errors.
const HypreParVector & GetEigenvector(unsigned int i) const
Extract a single eigenvector.
HYPRE_BigInt * GetColStarts() const
Return the parallel column partitioning array.
HypreParVector & operator=(double d)
Set constant values.
void SetAbsTol(double tol)
void PrintCommPkg(std::ostream &out=mfem::out) const
Print information about the hypre_ParCSRCommPkg of the HypreParMatrix.
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 ...
HypreParMatrix * ExtractSubmatrix(const Array< int > &indices, double threshold=0.0) const
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)
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0) const
Computes y = alpha * A * x + beta * y.
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)
double omega
SOR parameter (usually in (0,2))
double u(const Vector &xvec)
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...
void WrapHypreParCSRMatrix(hypre_ParCSRMatrix *a, bool owner=true)
Converts hypre's format to HypreParMatrix.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Wrapper for hypre's ParCSR matrix class.
void HostReadWrite()
Update the internal hypre_ParCSRMatrix object, A, to be on host.
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.
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.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's PCG.
HypreParMatrix * HypreParMatrixFromBlocks(Array2D< HypreParMatrix * > &blocks, Array2D< double > *blockCoeff)
Returns a merged hypre matrix constructed from hypre matrix blocks.
const T * Read(MemoryClass mc, int size) const
Get read-only access to the memory with the given MemoryClass.
Memory< double > & GetDiagMemoryData()
void Solve()
Solve the eigenproblem.
HypreParVector * V
Temporary vectors.
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)
MemoryType GetHostMemoryType() const
Return the host MemoryType of the Memory object.
virtual double * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
MemoryClass
Memory classes identify sets of memory types.
void WrapMemoryReadWrite(Memory< double > &mem)
Replace the HypreParVector's data with the given Memory, mem, and prepare the vector for read and wri...
int width
Dimension of the input / number of columns in the matrix.
int poly_order
Order of the smoothing polynomial.
void SetTol(HYPRE_Real tol)
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 ...
double sigma(const Vector &x)
void HypreReadWrite()
Update the internal hypre_ParCSRMatrix object, A, to be in hypre memory space.