12 #include "../config/config.hpp"
17 #include "../fem/fem.hpp"
18 #include "../general/forall.hpp"
25 #ifdef MFEM_USE_SUNDIALS
26 #include <nvector/nvector_parallel.h>
36 #if MFEM_HYPRE_VERSION >= 21900
45 void Hypre::Finalize()
47 Hypre &hypre = Instance();
50 #if MFEM_HYPRE_VERSION >= 21900
53 hypre.finalized =
true;
57 void Hypre::SetDefaultOptions()
62 #if MFEM_HYPRE_VERSION >= 22100
63 #ifdef HYPRE_USING_CUDA
65 HYPRE_SetSpGemmUseCusparse(0);
66 #elif defined(HYPRE_USING_HIP)
94 template<
typename TargetT,
typename SourceT>
95 static TargetT *DuplicateAs(
const SourceT *array,
int size,
96 bool cplusplus =
true)
98 TargetT *target_array = cplusplus ? (TargetT*) Memory<TargetT>(size)
99 : mfem_hypre_TAlloc_host(TargetT, size);
100 for (
int i = 0; i < size; i++)
102 target_array[i] = array[i];
111 template <
typename T>
116 if (src_d_mt == MemoryType::DEFAULT)
118 src_d_mt = MemoryManager::GetDualMemoryType(src_h_mt);
125 inline void HypreParVector::_SetDataAndSize_()
127 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
128 #if !defined(HYPRE_USING_GPU)
129 SetDataAndSize(hypre_VectorData(x_loc),
133 MemoryType mt = (hypre_VectorMemoryLocation(x_loc) == HYPRE_MEMORY_HOST
135 if (hypre_VectorData(x_loc) != NULL)
137 data.Wrap(hypre_VectorData(x_loc), size, mt,
false);
149 x = hypre_ParVectorCreate(comm,glob_size,col);
150 hypre_ParVectorInitialize(x);
151 #if MFEM_HYPRE_VERSION <= 22200
152 hypre_ParVectorSetPartitioningOwner(x,0);
155 hypre_ParVectorSetDataOwner(x,1);
156 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
166 x = hypre_ParVectorCreate(comm,glob_size,col);
167 hypre_ParVectorSetDataOwner(x,1);
168 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
169 hypre_SeqVectorSetDataOwner(x_loc,0);
170 #if MFEM_HYPRE_VERSION <= 22200
171 hypre_ParVectorSetPartitioningOwner(x,0);
174 hypre_VectorData(x_loc) = &tmp;
175 #ifdef HYPRE_USING_GPU
176 hypre_VectorMemoryLocation(x_loc) =
177 is_device_ptr ? HYPRE_MEMORY_DEVICE : HYPRE_MEMORY_HOST;
183 hypre_ParVectorInitialize(x);
185 hypre_VectorData(x_loc) = data_;
192 y.CreateCompatibleVector())
195 hypre_SeqVectorCopy(hypre_ParVectorLocalVector(y.x),
196 hypre_ParVectorLocalVector(x));
202 *
this = std::move(y);
210 x = hypre_ParVectorInDomainOf(const_cast<HypreParMatrix&>(A));
214 x = hypre_ParVectorInRangeOf(const_cast<HypreParMatrix&>(A));
222 x = (hypre_ParVector *) y;
231 hypre_ParVectorInitialize(x);
232 #if MFEM_HYPRE_VERSION <= 22200
233 hypre_ParVectorSetPartitioningOwner(x,0);
236 hypre_ParVectorSetDataOwner(x,1);
237 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
245 result.x = hypre_ParVectorCreate(x -> comm, x -> global_size,
247 hypre_ParVectorInitialize(result.x);
248 #if MFEM_HYPRE_VERSION <= 22200
249 hypre_ParVectorSetPartitioningOwner(result.x,0);
251 hypre_ParVectorSetDataOwner(result.x,1);
252 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(result.x),1);
253 result._SetDataAndSize_();
254 result.own_ParVector = 1;
261 if (own_ParVector) { hypre_ParVectorDestroy(x); }
265 own_ParVector = owner;
270 hypre_Vector *hv = hypre_ParVectorToVectorAll(*
this);
273 hypre_SeqVectorSetDataOwner(hv,0);
274 hypre_SeqVectorDestroy(hv);
287 if (size != y.
Size())
311 hypre_VectorData(hypre_ParVectorLocalVector(x)) = data_;
317 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
318 hypre_VectorData(x_loc) =
320 #ifdef HYPRE_USING_GPU
321 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
327 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
329 #ifdef HYPRE_USING_GPU
330 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
336 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
338 #ifdef HYPRE_USING_GPU
339 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
349 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
350 hypre_VectorData(x_loc) =
352 #ifdef HYPRE_USING_GPU
353 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
364 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
366 #ifdef HYPRE_USING_GPU
367 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
378 hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
380 #ifdef HYPRE_USING_GPU
381 hypre_VectorMemoryLocation(x_loc) = HYPRE_MEMORY_DEVICE;
388 return hypre_ParVectorSetRandomValues(x,seed);
393 hypre_ParVectorPrint(x,fname);
400 hypre_ParVectorDestroy(x);
403 x = hypre_ParVectorRead(comm, fname);
404 own_ParVector =
true;
412 hypre_ParVectorDestroy(x);
416 #ifdef MFEM_USE_SUNDIALS
423 #endif // MFEM_USE_SUNDIALS
428 return hypre_ParVectorInnerProd(*x, *y);
433 return hypre_ParVectorInnerProd(x, y);
442 double loc_norm = vec.
Norml1();
443 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
447 double loc_norm = vec*vec;
448 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
454 for (
int i = 0; i < vec.
Size(); i++)
456 sum +=
pow(fabs(vec(i)), p);
458 MPI_Allreduce(&sum, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
459 norm =
pow(norm, 1.0/p);
464 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_MAX, comm);
486 template <
typename T>
521 template <
typename SrcT,
typename DstT>
529 MFEM_FORALL(i, capacity, dst_p[i] = src_p[i];);
533 void HypreParMatrix::Init()
538 diagOwner = offdOwner = colMapOwner = -1;
550 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
551 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
552 const int num_rows =
NumRows();
555 diag->i =
const_cast<HYPRE_Int*
>(mem_diag.
I.
Read(mc, num_rows+1));
556 diag->j =
const_cast<HYPRE_Int*
>(mem_diag.
J.
Read(mc, diag_nnz));
557 diag->data =
const_cast<double*
>(mem_diag.
data.
Read(mc, diag_nnz));
558 offd->i =
const_cast<HYPRE_Int*
>(mem_offd.
I.
Read(mc, num_rows+1));
559 offd->j =
const_cast<HYPRE_Int*
>(mem_offd.
J.
Read(mc, offd_nnz));
560 offd->data =
const_cast<double*
>(mem_offd.
data.
Read(mc, offd_nnz));
561 #if MFEM_HYPRE_VERSION >= 21800
562 decltype(diag->memory_location) ml =
564 diag->memory_location = ml;
565 offd->memory_location = ml;
571 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
572 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
573 const int num_rows =
NumRows();
576 diag->i = mem_diag.
I.
ReadWrite(mc, num_rows+1);
579 offd->i = mem_offd.
I.
ReadWrite(mc, num_rows+1);
582 #if MFEM_HYPRE_VERSION >= 21800
583 decltype(diag->memory_location) ml =
585 diag->memory_location = ml;
586 offd->memory_location = ml;
590 void HypreParMatrix::Write(
MemoryClass mc,
bool set_diag,
bool set_offd)
592 hypre_CSRMatrix *diag = hypre_ParCSRMatrixDiag(A);
593 hypre_CSRMatrix *offd = hypre_ParCSRMatrixOffd(A);
606 #if MFEM_HYPRE_VERSION >= 21800
607 decltype(diag->memory_location) ml =
609 if (set_diag) { diag->memory_location = ml; }
610 if (set_offd) { offd->memory_location = ml; }
628 #if MFEM_HYPRE_VERSION >= 21800
629 MemoryType diag_mt = (A->diag->memory_location == HYPRE_MEMORY_HOST
631 MemoryType offd_mt = (A->offd->memory_location == HYPRE_MEMORY_HOST
637 diagOwner = HypreCsrToMem(A->diag, diag_mt,
false, mem_diag);
638 offdOwner = HypreCsrToMem(A->offd, offd_mt,
false, mem_offd);
644 hypre_CSRMatrix *hypre_csr,
659 const int num_rows = csr->
Height();
661 hypre_csr->i =
const_cast<HYPRE_Int*
>(mem_csr.
I.
Read(hypre_mc, num_rows+1));
662 hypre_csr->j =
const_cast<HYPRE_Int*
>(mem_csr.
J.
Read(hypre_mc, nnz));
663 hypre_csr->data =
const_cast<double*
>(mem_csr.
data.
Read(hypre_mc, nnz));
666 "invalid state: host ownership for I and J differ!");
671 signed char HypreParMatrix::CopyBoolCSR(Table *bool_csr,
672 MemoryIJData &mem_csr,
673 hypre_CSRMatrix *hypre_csr)
678 CopyMemory(bool_csr->GetIMemory(), mem_csr.I, hypre_mc,
false);
679 CopyMemory(bool_csr->GetJMemory(), mem_csr.J, hypre_mc,
false);
685 const int num_rows = bool_csr->Size();
686 const int nnz = bool_csr->Size_of_connections();
689 for (
int i = 0; i < nnz; i++)
693 hypre_csr->i =
const_cast<HYPRE_Int*
>(mem_csr.I.Read(hypre_mc, num_rows+1));
694 hypre_csr->j =
const_cast<HYPRE_Int*
>(mem_csr.J.Read(hypre_mc, nnz));
695 hypre_csr->data =
const_cast<double*
>(mem_csr.data.Read(hypre_mc, nnz));
697 MFEM_ASSERT(mem_csr.I.OwnsHostPtr() == mem_csr.J.OwnsHostPtr(),
698 "invalid state: host ownership for I and J differ!");
699 return (mem_csr.I.OwnsHostPtr() ? 1 : 0) +
700 (mem_csr.data.OwnsHostPtr() ? 2 : 0);
706 static void CopyCSR_J(
const int nnz,
const MemoryIJData &mem_csr,
712 MFEM_FORALL(i, nnz, dst_p[i] = src_p[i];);
717 signed char HypreParMatrix::HypreCsrToMem(hypre_CSRMatrix *h_mat,
724 mem.I.Wrap(h_mat->i, nr1, h_mat_mt, own_ija);
725 mem.J.Wrap(h_mat->j, nnz, h_mat_mt, own_ija);
726 mem.data.Wrap(h_mat->data, nnz, h_mat_mt, own_ija);
732 h_mem.I.New(nr1, hypre_mt);
733 h_mem.I.CopyFrom(mem.I, nr1);
735 h_mem.J.New(nnz, hypre_mt);
736 h_mem.J.CopyFrom(mem.J, nnz);
738 h_mem.data.New(nnz, hypre_mt);
739 h_mem.data.CopyFrom(mem.data, nnz);
748 #if MFEM_HYPRE_VERSION < 21400
749 hypre_TFree(h_mat->i);
750 #elif MFEM_HYPRE_VERSION < 21800
751 hypre_TFree(h_mat->i, HYPRE_MEMORY_SHARED);
753 hypre_TFree(h_mat->i, h_mat->memory_location);
755 if (h_mat->owns_data)
757 #if MFEM_HYPRE_VERSION < 21400
758 hypre_TFree(h_mat->j);
759 hypre_TFree(h_mat->data);
760 #elif MFEM_HYPRE_VERSION < 21800
761 hypre_TFree(h_mat->j, HYPRE_MEMORY_SHARED);
762 hypre_TFree(h_mat->data, HYPRE_MEMORY_SHARED);
764 hypre_TFree(h_mat->j, h_mat->memory_location);
765 hypre_TFree(h_mat->data, h_mat->memory_location);
769 h_mat->i = mem.I.ReadWrite(hypre_mc, nr1);
770 h_mat->j = mem.J.ReadWrite(hypre_mc, nnz);
771 h_mat->data = mem.data.ReadWrite(hypre_mc, nnz);
772 h_mat->owns_data = 0;
773 #if MFEM_HYPRE_VERSION >= 21800
774 h_mat->memory_location = HYPRE_MEMORY_DEVICE;
784 :
Operator(diag->Height(), diag->Width())
787 A = hypre_ParCSRMatrixCreate(comm, glob_size, glob_size, row_starts,
789 hypre_ParCSRMatrixSetDataOwner(A,1);
790 #if MFEM_HYPRE_VERSION <= 22200
791 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
792 hypre_ParCSRMatrixSetColStartsOwner(A,0);
795 hypre_CSRMatrixSetDataOwner(A->diag,0);
796 diagOwner = CopyCSR(diag, mem_diag, A->diag,
false);
797 hypre_CSRMatrixSetRownnz(A->diag);
799 hypre_CSRMatrixSetDataOwner(A->offd,1);
800 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
808 hypre_ParCSRMatrixSetNumNonzeros(A);
812 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
816 CopyCSR_J(A->diag->num_nonzeros, mem_diag, diag->
GetMemoryJ());
820 hypre_MatvecCommPkgCreate(A);
830 :
Operator(diag->Height(), diag->Width())
833 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
834 row_starts, col_starts,
836 hypre_ParCSRMatrixSetDataOwner(A,1);
837 #if MFEM_HYPRE_VERSION <= 22200
838 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
839 hypre_ParCSRMatrixSetColStartsOwner(A,0);
842 hypre_CSRMatrixSetDataOwner(A->diag,0);
843 diagOwner = CopyCSR(diag, mem_diag, A->diag,
false);
844 hypre_CSRMatrixSetRownnz(A->diag);
846 hypre_CSRMatrixSetDataOwner(A->offd,1);
847 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
850 hypre_ParCSRMatrixSetNumNonzeros(A);
853 if (row_starts == col_starts)
856 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
860 CopyCSR_J(A->diag->num_nonzeros, mem_diag, diag->
GetMemoryJ());
865 hypre_MatvecCommPkgCreate(A);
878 :
Operator(diag->Height(), diag->Width())
881 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
882 row_starts, col_starts,
885 hypre_ParCSRMatrixSetDataOwner(A,1);
886 #if MFEM_HYPRE_VERSION <= 22200
887 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
888 hypre_ParCSRMatrixSetColStartsOwner(A,0);
891 hypre_CSRMatrixSetDataOwner(A->diag,0);
892 diagOwner = CopyCSR(diag, mem_diag, A->diag, own_diag_offd);
893 if (own_diag_offd) {
delete diag; }
894 hypre_CSRMatrixSetRownnz(A->diag);
896 hypre_CSRMatrixSetDataOwner(A->offd,0);
897 offdOwner = CopyCSR(offd, mem_offd, A->offd, own_diag_offd);
898 if (own_diag_offd) {
delete offd; }
899 hypre_CSRMatrixSetRownnz(A->offd);
901 hypre_ParCSRMatrixColMapOffd(A) = cmap;
905 hypre_ParCSRMatrixSetNumNonzeros(A);
908 if (row_starts == col_starts)
911 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
915 CopyCSR_J(A->diag->num_nonzeros, mem_diag, diag->
GetMemoryJ());
920 hypre_MatvecCommPkgCreate(A);
929 HYPRE_Int *diag_i, HYPRE_Int *diag_j,
double *diag_data,
930 HYPRE_Int *offd_i, HYPRE_Int *offd_j,
double *offd_data,
935 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
936 row_starts, col_starts, offd_num_cols, 0, 0);
937 hypre_ParCSRMatrixSetDataOwner(A,1);
938 #if MFEM_HYPRE_VERSION <= 22200
939 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
940 hypre_ParCSRMatrixSetColStartsOwner(A,0);
943 HYPRE_Int local_num_rows = hypre_CSRMatrixNumRows(A->diag);
945 hypre_CSRMatrixSetDataOwner(A->diag, hypre_arrays);
946 hypre_CSRMatrixI(A->diag) = diag_i;
947 hypre_CSRMatrixJ(A->diag) = diag_j;
948 hypre_CSRMatrixData(A->diag) = diag_data;
949 hypre_CSRMatrixNumNonzeros(A->diag) = diag_i[local_num_rows];
950 #ifdef HYPRE_USING_GPU
951 hypre_CSRMatrixMemoryLocation(A->diag) = HYPRE_MEMORY_HOST;
953 hypre_CSRMatrixSetRownnz(A->diag);
955 hypre_CSRMatrixSetDataOwner(A->offd, hypre_arrays);
956 hypre_CSRMatrixI(A->offd) = offd_i;
957 hypre_CSRMatrixJ(A->offd) = offd_j;
958 hypre_CSRMatrixData(A->offd) = offd_data;
959 hypre_CSRMatrixNumNonzeros(A->offd) = offd_i[local_num_rows];
960 #ifdef HYPRE_USING_GPU
961 hypre_CSRMatrixMemoryLocation(A->offd) = HYPRE_MEMORY_HOST;
963 hypre_CSRMatrixSetRownnz(A->offd);
965 hypre_ParCSRMatrixColMapOffd(A) = offd_col_map;
967 colMapOwner = hypre_arrays ? -1 : 1;
969 hypre_ParCSRMatrixSetNumNonzeros(A);
972 if (row_starts == col_starts)
974 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
977 hypre_MatvecCommPkgCreate(A);
985 diagOwner = HypreCsrToMem(A->diag, host_mt,
true, mem_diag);
986 offdOwner = HypreCsrToMem(A->offd, host_mt,
true, mem_offd);
991 diagOwner = HypreCsrToMem(A->diag, host_mt,
false, mem_diag);
992 offdOwner = HypreCsrToMem(A->offd, host_mt,
false, mem_offd);
1003 MFEM_ASSERT(sm_a != NULL,
"invalid input");
1004 MFEM_VERIFY(!HYPRE_AssumedPartitionCheck(),
1005 "this method can not be used with assumed partition");
1009 hypre_CSRMatrix *csr_a;
1010 csr_a = hypre_CSRMatrixCreate(sm_a ->
Height(), sm_a ->
Width(),
1011 sm_a -> NumNonZeroElems());
1013 hypre_CSRMatrixSetDataOwner(csr_a,0);
1015 CopyCSR(sm_a, mem_a, csr_a,
false);
1016 hypre_CSRMatrixSetRownnz(csr_a);
1020 hypre_ParCSRMatrix *new_A =
1021 hypre_CSRMatrixToParCSRMatrix(comm, csr_a, row_starts, col_starts);
1027 hypre_CSRMatrixI(csr_a) = NULL;
1028 hypre_CSRMatrixDestroy(csr_a);
1031 if (row_starts == col_starts)
1033 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(new_A));
1036 hypre_MatvecCommPkgCreate(A);
1051 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
1052 row_starts, col_starts, 0, nnz, 0);
1053 hypre_ParCSRMatrixSetDataOwner(A,1);
1054 #if MFEM_HYPRE_VERSION <= 22200
1055 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
1056 hypre_ParCSRMatrixSetColStartsOwner(A,0);
1059 hypre_CSRMatrixSetDataOwner(A->diag,0);
1060 diagOwner = CopyBoolCSR(diag, mem_diag, A->diag);
1061 hypre_CSRMatrixSetRownnz(A->diag);
1063 hypre_CSRMatrixSetDataOwner(A->offd,1);
1064 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Size()+1);
1067 hypre_ParCSRMatrixSetNumNonzeros(A);
1070 if (row_starts == col_starts)
1073 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1080 hypre_MatvecCommPkgCreate(A);
1090 HYPRE_Int *i_diag, HYPRE_Int *j_diag,
1091 HYPRE_Int *i_offd, HYPRE_Int *j_offd,
1094 HYPRE_Int diag_nnz, offd_nnz;
1097 if (HYPRE_AssumedPartitionCheck())
1099 diag_nnz = i_diag[row[1]-row[0]];
1100 offd_nnz = i_offd[row[1]-row[0]];
1102 A = hypre_ParCSRMatrixCreate(comm, row[2], col[2], row, col,
1103 cmap_size, diag_nnz, offd_nnz);
1107 diag_nnz = i_diag[row[
id+1]-row[id]];
1108 offd_nnz = i_offd[row[
id+1]-row[id]];
1110 A = hypre_ParCSRMatrixCreate(comm, row[np], col[np], row, col,
1111 cmap_size, diag_nnz, offd_nnz);
1114 hypre_ParCSRMatrixSetDataOwner(A,1);
1115 #if MFEM_HYPRE_VERSION <= 22200
1116 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
1117 hypre_ParCSRMatrixSetColStartsOwner(A,0);
1121 for (HYPRE_Int i = 0; i < diag_nnz; i++)
1123 mem_diag.
data[i] = 1.0;
1127 for (HYPRE_Int i = 0; i < offd_nnz; i++)
1129 mem_offd.
data[i] = 1.0;
1132 hypre_CSRMatrixSetDataOwner(A->diag,0);
1133 hypre_CSRMatrixI(A->diag) = i_diag;
1134 hypre_CSRMatrixJ(A->diag) = j_diag;
1135 hypre_CSRMatrixData(A->diag) = mem_diag.
data;
1136 #ifdef HYPRE_USING_GPU
1137 hypre_CSRMatrixMemoryLocation(A->diag) = HYPRE_MEMORY_HOST;
1139 hypre_CSRMatrixSetRownnz(A->diag);
1141 hypre_CSRMatrixSetDataOwner(A->offd,0);
1142 hypre_CSRMatrixI(A->offd) = i_offd;
1143 hypre_CSRMatrixJ(A->offd) = j_offd;
1144 hypre_CSRMatrixData(A->offd) = mem_offd.
data;
1145 #ifdef HYPRE_USING_GPU
1146 hypre_CSRMatrixMemoryLocation(A->offd) = HYPRE_MEMORY_HOST;
1148 hypre_CSRMatrixSetRownnz(A->offd);
1150 hypre_ParCSRMatrixColMapOffd(A) = cmap;
1154 hypre_ParCSRMatrixSetNumNonzeros(A);
1159 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1162 hypre_MatvecCommPkgCreate(A);
1168 diagOwner = HypreCsrToMem(A->diag, host_mt,
true, mem_diag);
1169 offdOwner = HypreCsrToMem(A->offd, host_mt,
true, mem_offd);
1189 if (HYPRE_AssumedPartitionCheck())
1192 my_col_start = cols[0];
1193 my_col_end = cols[1];
1198 MPI_Comm_rank(comm, &myid);
1199 MPI_Comm_size(comm, &part_size);
1201 my_col_start = cols[myid];
1202 my_col_end = cols[myid+1];
1209 row_starts = col_starts = mfem_hypre_TAlloc_host(
HYPRE_BigInt, part_size);
1210 for (
int i = 0; i < part_size; i++)
1212 row_starts[i] = rows[i];
1217 row_starts = mfem_hypre_TAlloc_host(
HYPRE_BigInt, part_size);
1218 col_starts = mfem_hypre_TAlloc_host(
HYPRE_BigInt, part_size);
1219 for (
int i = 0; i < part_size; i++)
1221 row_starts[i] = rows[i];
1222 col_starts[i] = cols[i];
1228 HYPRE_Int diag_nnz = 0, offd_nnz = 0, offd_num_cols = 0;
1229 map<HYPRE_BigInt, HYPRE_Int> offd_map;
1230 for (HYPRE_Int j = 0, loc_nnz = I[nrows]; j < loc_nnz; j++)
1233 if (my_col_start <= glob_col && glob_col < my_col_end)
1239 offd_map.insert(pair<const HYPRE_BigInt, HYPRE_Int>(glob_col, -1));
1244 for (
auto it = offd_map.begin(); it != offd_map.end(); ++it)
1246 it->second = offd_num_cols++;
1250 A = hypre_ParCSRMatrixCreate(comm, glob_nrows, glob_ncols,
1251 row_starts, col_starts, offd_num_cols,
1252 diag_nnz, offd_nnz);
1253 hypre_ParCSRMatrixInitialize(A);
1259 HYPRE_Int *diag_i, *diag_j, *offd_i, *offd_j;
1261 double *diag_data, *offd_data;
1262 diag_i = A->diag->i;
1263 diag_j = A->diag->j;
1264 diag_data = A->diag->data;
1265 offd_i = A->offd->i;
1266 offd_j = A->offd->j;
1267 offd_data = A->offd->data;
1268 offd_col_map = A->col_map_offd;
1270 diag_nnz = offd_nnz = 0;
1271 for (HYPRE_Int i = 0, j = 0; i < nrows; i++)
1273 diag_i[i] = diag_nnz;
1274 offd_i[i] = offd_nnz;
1275 for (HYPRE_Int j_end = I[i+1]; j < j_end; j++)
1278 if (my_col_start <= glob_col && glob_col < my_col_end)
1280 diag_j[diag_nnz] = glob_col - my_col_start;
1281 diag_data[diag_nnz] = data[j];
1286 offd_j[offd_nnz] = offd_map[glob_col];
1287 offd_data[offd_nnz] = data[j];
1292 diag_i[nrows] = diag_nnz;
1293 offd_i[nrows] = offd_nnz;
1294 for (
auto it = offd_map.begin(); it != offd_map.end(); ++it)
1296 offd_col_map[it->second] = it->first;
1299 hypre_ParCSRMatrixSetNumNonzeros(A);
1301 if (row_starts == col_starts)
1303 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1305 #if MFEM_HYPRE_VERSION > 22200
1306 mfem_hypre_TFree_host(row_starts);
1309 mfem_hypre_TFree_host(col_starts);
1312 hypre_MatvecCommPkgCreate(A);
1322 hypre_ParCSRMatrix *Ph =
static_cast<hypre_ParCSRMatrix *
>(P);
1327 A = hypre_ParCSRMatrixCompleteClone(Ph);
1329 hypre_ParCSRMatrixCopy(Ph, A, 1);
1337 hypre_ParCSRMatrixSetNumNonzeros(A);
1339 hypre_MatvecCommPkgCreate(A);
1368 MFEM_ASSERT(diagOwner < 0 && offdOwner < 0 && colMapOwner == -1,
"");
1369 MFEM_ASSERT(diagOwner == offdOwner,
"");
1370 MFEM_ASSERT(ParCSROwner,
"");
1371 hypre_ParCSRMatrix *R = A;
1372 #ifdef HYPRE_USING_GPU
1376 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 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);
1704 double a,
double b)
const
1708 return hypre_ParCSRMatrixMatvec(a, A, x, b, y);
1713 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1714 <<
", expected size = " <<
Width());
1715 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1716 <<
", expected size = " <<
Height());
1763 hypre_ParCSRMatrixMatvec(a, A, *X, b, *Y);
1765 if (!yshallow) { y = *Y; }
1771 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
1772 <<
", expected size = " <<
Height());
1773 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
1774 <<
", expected size = " <<
Width());
1825 hypre_ParCSRMatrixMatvecT(a, A, *Y, b, *X);
1827 if (!yshallow) { y = *X; }
1831 double a,
double b)
const
1833 return hypre_ParCSRMatrixMatvec(a, A, (hypre_ParVector *) x, b,
1834 (hypre_ParVector *) y);
1838 double a,
double b)
const
1842 return hypre_ParCSRMatrixMatvecT(a, A, x, b, y);
1848 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1849 <<
", expected size = " <<
Width());
1850 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1851 <<
", expected size = " <<
Height());
1857 internal::hypre_ParCSRMatrixAbsMatvec(A, a, const_cast<double*>(x_data),
1865 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
1866 <<
", expected size = " <<
Height());
1867 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
1868 <<
", expected size = " <<
Width());
1874 internal::hypre_ParCSRMatrixAbsMatvecT(A, a, const_cast<double*>(x_data),
1882 const bool assumed_partition = HYPRE_AssumedPartitionCheck();
1883 const bool row_starts_given = (row_starts != NULL);
1884 if (!row_starts_given)
1886 row_starts = hypre_ParCSRMatrixRowStarts(A);
1887 MFEM_VERIFY(D.
Height() == hypre_CSRMatrixNumRows(A->diag),
1888 "the matrix D is NOT compatible with the row starts of"
1889 " this HypreParMatrix, row_starts must be given.");
1894 if (assumed_partition)
1900 MPI_Comm_rank(
GetComm(), &offset);
1902 int local_num_rows = row_starts[offset+1]-row_starts[offset];
1903 MFEM_VERIFY(local_num_rows == D.
Height(),
"the number of rows in D is "
1904 " not compatible with the given row_starts");
1911 if (assumed_partition)
1914 if (row_starts_given)
1916 global_num_rows = row_starts[2];
1923 global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
1928 MPI_Comm_size(
GetComm(), &part_size);
1929 global_num_rows = row_starts[part_size];
1933 HYPRE_BigInt *col_starts = hypre_ParCSRMatrixColStarts(A);
1939 GetOffd(A_offd, col_map_offd);
1949 DuplicateAs<HYPRE_BigInt>(row_starts, part_size,
false);
1951 (row_starts == col_starts ? new_row_starts :
1952 DuplicateAs<HYPRE_BigInt>(col_starts, part_size,
false));
1954 DuplicateAs<HYPRE_BigInt>(col_map_offd, A_offd.
Width());
1958 const bool own_diag_offd =
true;
1963 global_num_rows, hypre_ParCSRMatrixGlobalNumCols(A),
1964 new_row_starts, new_col_starts,
1965 DA_diag, DA_offd, new_col_map_offd,
1968 #if MFEM_HYPRE_VERSION <= 22200
1970 hypre_ParCSRMatrixSetRowStartsOwner(DA->A, 1);
1971 hypre_ParCSRMatrixSetColStartsOwner(DA->A, 1);
1973 mfem_hypre_TFree_host(new_row_starts);
1974 mfem_hypre_TFree_host(new_col_starts);
1976 DA->colMapOwner = 1;
1983 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
1988 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
1990 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
1997 double *Adiag_data = hypre_CSRMatrixData(A->diag);
1998 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
2000 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
2001 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
2004 for (
int i(0); i < size; ++i)
2007 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
2009 Adiag_data[jj] *= val;
2011 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
2013 Aoffd_data[jj] *= val;
2022 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
2027 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
2029 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
2036 double *Adiag_data = hypre_CSRMatrixData(A->diag);
2037 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
2040 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
2041 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
2044 for (
int i(0); i < size; ++i)
2049 mfem_error(
"HypreParMatrix::InvDiagScale : Division by 0");
2053 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
2055 Adiag_data[jj] *= val;
2057 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
2059 Aoffd_data[jj] *= val;
2068 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
2075 HYPRE_Int size=hypre_CSRMatrixNumRows(A->diag);
2078 double *Adiag_data = hypre_CSRMatrixData(A->diag);
2079 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
2080 for (jj = 0; jj < Adiag_i[size]; ++jj)
2082 Adiag_data[jj] *=
s;
2085 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
2086 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
2087 for (jj = 0; jj < Aoffd_i[size]; ++jj)
2089 Aoffd_data[jj] *=
s;
2095 static void get_sorted_rows_cols(
const Array<int> &rows_cols,
2101 for (
int i = 0; i < rows_cols.
Size(); i++)
2103 hypre_sorted[i] = rows_cols[i];
2104 if (i && rows_cols[i-1] > rows_cols[i]) { sorted =
false; }
2106 if (!sorted) { hypre_sorted.
Sort(); }
2114 hypre_CSRMatrix * csr_A;
2115 hypre_CSRMatrix * csr_A_wo_z;
2116 hypre_ParCSRMatrix * parcsr_A_ptr;
2121 comm = hypre_ParCSRMatrixComm(A);
2123 ierr += hypre_ParCSRMatrixGetLocalRange(A,
2124 &row_start,&row_end,
2125 &col_start,&col_end );
2127 row_starts = hypre_ParCSRMatrixRowStarts(A);
2128 col_starts = hypre_ParCSRMatrixColStarts(A);
2130 #if MFEM_HYPRE_VERSION <= 22200
2131 bool old_owns_row = hypre_ParCSRMatrixOwnsRowStarts(A);
2132 bool old_owns_col = hypre_ParCSRMatrixOwnsColStarts(A);
2134 HYPRE_BigInt global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
2135 HYPRE_BigInt global_num_cols = hypre_ParCSRMatrixGlobalNumCols(A);
2136 parcsr_A_ptr = hypre_ParCSRMatrixCreate(comm, global_num_rows,
2138 row_starts, col_starts,
2140 #if MFEM_HYPRE_VERSION <= 22200
2141 hypre_ParCSRMatrixOwnsRowStarts(parcsr_A_ptr) = old_owns_row;
2142 hypre_ParCSRMatrixOwnsColStarts(parcsr_A_ptr) = old_owns_col;
2143 hypre_ParCSRMatrixOwnsRowStarts(A) = 0;
2144 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
2147 csr_A = hypre_MergeDiagAndOffd(A);
2153 csr_A_wo_z = hypre_CSRMatrixDeleteZeros(csr_A,threshold);
2157 if (csr_A_wo_z == NULL)
2163 ierr += hypre_CSRMatrixDestroy(csr_A);
2169 ierr += GenerateDiagAndOffd(csr_A_wo_z,parcsr_A_ptr,
2172 ierr += hypre_CSRMatrixDestroy(csr_A_wo_z);
2174 MFEM_VERIFY(ierr == 0,
"");
2178 hypre_ParCSRMatrixSetNumNonzeros(A);
2180 #if MFEM_HYPRE_VERSION <= 22200
2181 if (row_starts == col_starts)
2183 if ((row_starts[0] == col_starts[0]) &&
2184 (row_starts[1] == col_starts[1]))
2187 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
2189 hypre_MatvecCommPkgCreate(A);
2196 HYPRE_Int old_err = hypre_error_flag;
2197 hypre_error_flag = 0;
2199 #if MFEM_HYPRE_VERSION < 21400
2201 double threshold = 0.0;
2204 HYPRE_Int *diag_I = A->diag->i, *offd_I = A->offd->i;
2205 double *diag_d = A->diag->data, *offd_d = A->offd->data;
2206 HYPRE_Int local_num_rows = A->diag->num_rows;
2207 double max_l2_row_norm = 0.0;
2209 for (HYPRE_Int r = 0; r < local_num_rows; r++)
2212 double l2_row_norm = row.
Norml2();
2214 l2_row_norm = std::hypot(l2_row_norm, row.
Norml2());
2215 max_l2_row_norm = std::max(max_l2_row_norm, l2_row_norm);
2217 double loc_max_l2_row_norm = max_l2_row_norm;
2218 MPI_Allreduce(&loc_max_l2_row_norm, &max_l2_row_norm, 1, MPI_DOUBLE,
2220 threshold = tol * max_l2_row_norm;
2225 #elif MFEM_HYPRE_VERSION < 21800
2227 HYPRE_Int err_flag = hypre_ParCSRMatrixDropSmallEntries(A, tol);
2228 MFEM_VERIFY(!err_flag,
"error encountered: error code = " << err_flag);
2232 HYPRE_Int err_flag = hypre_ParCSRMatrixDropSmallEntries(A, tol, 2);
2233 MFEM_VERIFY(!err_flag,
"error encountered: error code = " << err_flag);
2237 hypre_error_flag = old_err;
2245 get_sorted_rows_cols(rows_cols, rc_sorted);
2247 internal::hypre_ParCSRMatrixEliminateAXB(
2254 get_sorted_rows_cols(rows_cols, rc_sorted);
2256 hypre_ParCSRMatrix* Ae;
2258 internal::hypre_ParCSRMatrixEliminateAAe(
2268 get_sorted_rows_cols(cols, rc_sorted);
2270 hypre_ParCSRMatrix* Ae;
2272 internal::hypre_ParCSRMatrixEliminateAAe(
2273 A, &Ae, rc_sorted.
Size(), rc_sorted.
GetData(), 1);
2281 if (rows.
Size() > 0)
2284 get_sorted_rows_cols(rows, r_sorted);
2286 internal::hypre_ParCSRMatrixEliminateRows(A, r_sorted.
Size(),
2297 Ae.
Mult(-1.0, x, 1.0, b);
2301 if (ess_dof_list.
Size() == 0) {
return; }
2304 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
2305 double *data = hypre_CSRMatrixData(A_diag);
2306 HYPRE_Int *I = hypre_CSRMatrixI(A_diag);
2308 HYPRE_Int *J = hypre_CSRMatrixJ(A_diag);
2309 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd(A);
2310 HYPRE_Int *I_offd = hypre_CSRMatrixI(A_offd);
2311 double *data_offd = hypre_CSRMatrixData(A_offd);
2318 for (
int i = 0; i < ess_dof_list.
Size(); i++)
2320 int r = ess_dof_list[i];
2321 b(r) = data[I[r]] * x(r);
2323 MFEM_ASSERT(I[r] < I[r+1],
"empty row found!");
2329 MFEM_ABORT(
"the diagonal entry must be the first entry in the row!");
2331 for (
int j = I[r]+1; j < I[r+1]; j++)
2335 MFEM_ABORT(
"all off-diagonal entries must be zero!");
2338 for (
int j = I_offd[r]; j < I_offd[r+1]; j++)
2340 if (data_offd[j] != 0.0)
2342 MFEM_ABORT(
"all off-diagonal entries must be zero!");
2351 HYPRE_Int offj)
const
2354 hypre_ParCSRMatrixPrintIJ(A,offi,offj,fname);
2358 void HypreParMatrix::Read(MPI_Comm comm,
const char *fname)
2363 HYPRE_Int base_i, base_j;
2364 hypre_ParCSRMatrixReadIJ(comm, fname, &base_i, &base_j, &A);
2365 hypre_ParCSRMatrixSetNumNonzeros(A);
2367 hypre_MatvecCommPkgCreate(A);
2378 HYPRE_IJMatrix A_ij;
2379 HYPRE_IJMatrixRead(fname, comm, 5555, &A_ij);
2381 HYPRE_ParCSRMatrix A_parcsr;
2382 HYPRE_IJMatrixGetObject(A_ij, (
void**) &A_parcsr);
2384 A = (hypre_ParCSRMatrix*)A_parcsr;
2386 hypre_ParCSRMatrixSetNumNonzeros(A);
2388 hypre_MatvecCommPkgCreate(A);
2396 hypre_ParCSRCommPkg *comm_pkg = A->comm_pkg;
2397 MPI_Comm comm = A->comm;
2399 const int tag = 46801;
2401 MPI_Comm_rank(comm, &myid);
2402 MPI_Comm_size(comm, &nproc);
2406 MPI_Recv(&c, 1, MPI_CHAR, myid-1, tag, comm, MPI_STATUS_IGNORE);
2410 os <<
"\nHypreParMatrix: hypre_ParCSRCommPkg:\n";
2412 os <<
"Rank " << myid <<
":\n"
2413 " number of sends = " << comm_pkg->num_sends <<
2414 " (" <<
sizeof(double)*comm_pkg->send_map_starts[comm_pkg->num_sends] <<
2416 " number of recvs = " << comm_pkg->num_recvs <<
2417 " (" <<
sizeof(
double)*comm_pkg->recv_vec_starts[comm_pkg->num_recvs] <<
2419 if (myid != nproc-1)
2422 MPI_Send(&c, 1, MPI_CHAR, myid+1, tag, comm);
2435 os <<
"global number of rows : " << A->global_num_rows <<
'\n'
2436 <<
"global number of columns : " << A->global_num_cols <<
'\n'
2437 <<
"first row index : " << A->first_row_index <<
'\n'
2438 <<
" last row index : " << A->last_row_index <<
'\n'
2439 <<
"first col diag : " << A->first_col_diag <<
'\n'
2440 <<
" last col diag : " << A->last_col_diag <<
'\n'
2441 <<
"number of nonzeros : " << A->num_nonzeros <<
'\n';
2443 hypre_CSRMatrix *csr = A->diag;
2444 const char *csr_name =
"diag";
2445 for (
int m = 0; m < 2; m++)
2447 auto csr_nnz = csr->i[csr->num_rows];
2448 os << csr_name <<
" num rows : " << csr->num_rows <<
'\n'
2449 << csr_name <<
" num cols : " << csr->num_cols <<
'\n'
2450 << csr_name <<
" num nnz : " << csr->num_nonzeros <<
'\n'
2451 << csr_name <<
" i last : " << csr_nnz
2452 << (csr_nnz == csr->num_nonzeros ?
2453 " [good]" :
" [** BAD **]") <<
'\n';
2455 os << csr_name <<
" i hash : " << hf.
GetHash() <<
'\n';
2456 os << csr_name <<
" j hash : ";
2457 if (csr->j ==
nullptr)
2466 #if MFEM_HYPRE_VERSION >= 21600
2467 os << csr_name <<
" big j hash : ";
2468 if (csr->big_j ==
nullptr)
2478 os << csr_name <<
" data hash : ";
2479 if (csr->data ==
nullptr)
2493 hf.
AppendInts(A->col_map_offd, A->offd->num_cols);
2494 os <<
"col map offd hash : " << hf.
GetHash() <<
'\n';
2499 HYPRE_BigInt *A_col_map_offd = hypre_ParCSRMatrixColMapOffd(A);
2500 int size = hypre_CSRMatrixNumCols(hypre_ParCSRMatrixOffd(A));
2504 void HypreParMatrix::Destroy()
2506 if ( X != NULL ) {
delete X; }
2507 if ( Y != NULL ) {
delete Y; }
2511 if (A == NULL) {
return; }
2513 #ifdef HYPRE_USING_GPU
2514 if (ParCSROwner && (diagOwner < 0 || offdOwner < 0))
2522 MFEM_VERIFY(!(diagOwner < 0 && offdOwner < 0) || diagOwner == offdOwner,
2525 MemoryClass mc = (diagOwner == -1 || offdOwner == -1) ?
2527 Write(mc, diagOwner < 0, offdOwner <0);
2536 hypre_CSRMatrixI(A->diag) = NULL;
2537 hypre_CSRMatrixJ(A->diag) = NULL;
2538 hypre_CSRMatrixData(A->diag) = NULL;
2545 hypre_CSRMatrixI(A->offd) = NULL;
2546 hypre_CSRMatrixJ(A->offd) = NULL;
2547 hypre_CSRMatrixData(A->offd) = NULL;
2549 if (colMapOwner >= 0)
2551 if (colMapOwner & 1)
2555 hypre_ParCSRMatrixColMapOffd(A) = NULL;
2560 hypre_ParCSRMatrixDestroy(A);
2564 #if MFEM_HYPRE_VERSION >= 21800
2573 hypre_ParCSRMatrix *C_hypre;
2574 hypre_ParcsrBdiagInvScal(*A, blocksize, &C_hypre);
2575 hypre_ParCSRMatrixDropSmallEntries(C_hypre, 1e-15, 1);
2585 hypre_ParVector *d_hypre;
2586 hypre_ParvecBdiagInvScal(b_Hypre, blocksize, &d_hypre, *A);
2594 #if MFEM_HYPRE_VERSION < 21400
2599 hypre_ParCSRMatrix *C_hypre =
2600 internal::hypre_ParCSRMatrixAdd(const_cast<HypreParMatrix &>(A),
2601 const_cast<HypreParMatrix &>(B));
2602 MFEM_VERIFY(C_hypre,
"error in hypre_ParCSRMatrixAdd");
2604 hypre_MatvecCommPkgCreate(C_hypre);
2615 hypre_ParCSRMatrix * C = internal::hypre_ParCSRMatrixAdd(*A,*B);
2617 hypre_MatvecCommPkgCreate(C);
2624 HypreParMatrix *
Add(
double alpha,
const HypreParMatrix &A,
2625 double beta,
const HypreParMatrix &B)
2627 hypre_ParCSRMatrix *C;
2628 #if MFEM_HYPRE_VERSION <= 22000
2629 hypre_ParcsrAdd(alpha, A, beta, B, &C);
2631 hypre_ParCSRMatrixAdd(alpha, A, beta, B, &C);
2633 hypre_MatvecCommPkgCreate(C);
2635 return new HypreParMatrix(C);
2638 HypreParMatrix *
ParAdd(
const HypreParMatrix *A,
const HypreParMatrix *B)
2640 hypre_ParCSRMatrix *C;
2641 #if MFEM_HYPRE_VERSION <= 22000
2642 hypre_ParcsrAdd(1.0, *A, 1.0, *B, &C);
2644 hypre_ParCSRMatrixAdd(1.0, *A, 1.0, *B, &C);
2647 return new HypreParMatrix(C);
2655 hypre_ParCSRMatrix * ab;
2656 #ifdef HYPRE_USING_GPU
2657 ab = hypre_ParCSRMatMat(*A, *B);
2659 ab = hypre_ParMatmul(*A,*B);
2661 hypre_ParCSRMatrixSetNumNonzeros(ab);
2663 hypre_MatvecCommPkgCreate(ab);
2675 hypre_ParCSRMatrix * rap;
2677 #ifdef HYPRE_USING_GPU
2685 hypre_ParCSRMatrix *Q = hypre_ParCSRMatMat(*A,*P);
2686 const bool keepTranspose =
false;
2687 rap = hypre_ParCSRTMatMatKT(*P,Q,keepTranspose);
2688 hypre_ParCSRMatrixDestroy(Q);
2694 #if MFEM_HYPRE_VERSION <= 22200
2695 HYPRE_Int P_owns_its_col_starts =
2696 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
2699 hypre_BoomerAMGBuildCoarseOperator(*P,*A,*P,&rap);
2701 #if MFEM_HYPRE_VERSION <= 22200
2704 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
2705 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
2706 if (P_owns_its_col_starts)
2708 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
2713 hypre_ParCSRMatrixSetNumNonzeros(rap);
2722 hypre_ParCSRMatrix * rap;
2724 #ifdef HYPRE_USING_GPU
2726 hypre_ParCSRMatrix *Q = hypre_ParCSRMatMat(*A,*P);
2727 rap = hypre_ParCSRTMatMat(*Rt,Q);
2728 hypre_ParCSRMatrixDestroy(Q);
2731 #if MFEM_HYPRE_VERSION <= 22200
2732 HYPRE_Int P_owns_its_col_starts =
2733 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
2734 HYPRE_Int Rt_owns_its_col_starts =
2735 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*Rt));
2738 hypre_BoomerAMGBuildCoarseOperator(*Rt,*A,*P,&rap);
2740 #if MFEM_HYPRE_VERSION <= 22200
2743 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
2744 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
2745 if (P_owns_its_col_starts)
2747 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
2749 if (Rt_owns_its_col_starts)
2751 hypre_ParCSRMatrixSetColStartsOwner(*Rt, 1);
2756 hypre_ParCSRMatrixSetNumNonzeros(rap);
2765 const int num_loc,
const Array<int> &offsets,
2766 std::vector<int> &all_num_loc,
const int numBlocks,
2767 std::vector<std::vector<HYPRE_BigInt>> &blockProcOffsets,
2768 std::vector<HYPRE_BigInt> &procOffsets,
2769 std::vector<std::vector<int>> &procBlockOffsets,
2772 std::vector<std::vector<int>> all_block_num_loc(numBlocks);
2774 MPI_Allgather(&num_loc, 1, MPI_INT, all_num_loc.data(), 1, MPI_INT, comm);
2776 for (
int j = 0; j < numBlocks; ++j)
2778 all_block_num_loc[j].resize(nprocs);
2779 blockProcOffsets[j].resize(nprocs);
2781 const int blockNumRows = offsets[j + 1] - offsets[j];
2782 MPI_Allgather(&blockNumRows, 1, MPI_INT, all_block_num_loc[j].data(), 1,
2784 blockProcOffsets[j][0] = 0;
2785 for (
int i = 0; i < nprocs - 1; ++i)
2787 blockProcOffsets[j][i + 1] = blockProcOffsets[j][i]
2788 + all_block_num_loc[j][i];
2795 for (
int i = 0; i < nprocs; ++i)
2797 globalNum += all_num_loc[i];
2800 MFEM_VERIFY(globalNum >= 0,
"overflow in global size");
2804 firstLocal += all_num_loc[i];
2809 procOffsets[i + 1] = procOffsets[i] + all_num_loc[i];
2812 procBlockOffsets[i].resize(numBlocks);
2813 procBlockOffsets[i][0] = 0;
2814 for (
int j = 1; j < numBlocks; ++j)
2816 procBlockOffsets[i][j] = procBlockOffsets[i][j - 1]
2817 + all_block_num_loc[j - 1][i];
2825 const int numBlockRows = blocks.
NumRows();
2826 const int numBlockCols = blocks.
NumCols();
2828 MFEM_VERIFY(numBlockRows > 0 &&
2829 numBlockCols > 0,
"Invalid input to HypreParMatrixFromBlocks");
2831 if (blockCoeff != NULL)
2833 MFEM_VERIFY(numBlockRows == blockCoeff->
NumRows() &&
2834 numBlockCols == blockCoeff->
NumCols(),
2835 "Invalid input to HypreParMatrixFromBlocks");
2841 int nonNullBlockRow0 = -1;
2842 for (
int j=0; j<numBlockCols; ++j)
2844 if (blocks(0,j) != NULL)
2846 nonNullBlockRow0 = j;
2851 MFEM_VERIFY(nonNullBlockRow0 >= 0,
"Null row of blocks");
2852 MPI_Comm comm = blocks(0,nonNullBlockRow0)->GetComm();
2857 for (
int i=0; i<numBlockRows; ++i)
2859 for (
int j=0; j<numBlockCols; ++j)
2861 if (blocks(i,j) != NULL)
2863 const int nrows = blocks(i,j)->
NumRows();
2864 const int ncols = blocks(i,j)->
NumCols();
2866 MFEM_VERIFY(nrows > 0 &&
2867 ncols > 0,
"Invalid block in HypreParMatrixFromBlocks");
2869 if (rowOffsets[i+1] == 0)
2871 rowOffsets[i+1] = nrows;
2875 MFEM_VERIFY(rowOffsets[i+1] == nrows,
2876 "Inconsistent blocks in HypreParMatrixFromBlocks");
2879 if (colOffsets[j+1] == 0)
2881 colOffsets[j+1] = ncols;
2885 MFEM_VERIFY(colOffsets[j+1] == ncols,
2886 "Inconsistent blocks in HypreParMatrixFromBlocks");
2891 MFEM_VERIFY(rowOffsets[i+1] > 0,
"Invalid input blocks");
2892 rowOffsets[i+1] += rowOffsets[i];
2895 for (
int j=0; j<numBlockCols; ++j)
2897 MFEM_VERIFY(colOffsets[j+1] > 0,
"Invalid input blocks");
2898 colOffsets[j+1] += colOffsets[j];
2901 const int num_loc_rows = rowOffsets[numBlockRows];
2902 const int num_loc_cols = colOffsets[numBlockCols];
2905 MPI_Comm_rank(comm, &rank);
2906 MPI_Comm_size(comm, &nprocs);
2908 std::vector<int> all_num_loc_rows(nprocs);
2909 std::vector<int> all_num_loc_cols(nprocs);
2910 std::vector<HYPRE_BigInt> procRowOffsets(nprocs);
2911 std::vector<HYPRE_BigInt> procColOffsets(nprocs);
2912 std::vector<std::vector<HYPRE_BigInt>> blockRowProcOffsets(numBlockRows);
2913 std::vector<std::vector<HYPRE_BigInt>> blockColProcOffsets(numBlockCols);
2914 std::vector<std::vector<int>> procBlockRowOffsets(nprocs);
2915 std::vector<std::vector<int>> procBlockColOffsets(nprocs);
2917 HYPRE_BigInt first_loc_row, glob_nrows, first_loc_col, glob_ncols;
2919 all_num_loc_rows, numBlockRows, blockRowProcOffsets,
2920 procRowOffsets, procBlockRowOffsets, first_loc_row,
2924 all_num_loc_cols, numBlockCols, blockColProcOffsets,
2925 procColOffsets, procBlockColOffsets, first_loc_col,
2928 std::vector<int> opI(num_loc_rows + 1);
2929 std::vector<int> cnt(num_loc_rows);
2931 for (
int i = 0; i < num_loc_rows; ++i)
2937 opI[num_loc_rows] = 0;
2942 for (
int i = 0; i < numBlockRows; ++i)
2944 for (
int j = 0; j < numBlockCols; ++j)
2946 if (blocks(i, j) == NULL)
2948 csr_blocks(i, j) = NULL;
2952 blocks(i, j)->HostRead();
2953 csr_blocks(i, j) = hypre_MergeDiagAndOffd(*blocks(i, j));
2954 blocks(i, j)->HypreRead();
2956 for (
int k = 0; k < csr_blocks(i, j)->num_rows; ++k)
2958 opI[rowOffsets[i] + k + 1] +=
2959 csr_blocks(i, j)->i[k + 1] - csr_blocks(i, j)->i[k];
2966 for (
int i = 0; i < num_loc_rows; ++i)
2968 opI[i + 1] += opI[i];
2971 const int nnz = opI[num_loc_rows];
2973 std::vector<HYPRE_BigInt> opJ(nnz);
2974 std::vector<double> data(nnz);
2977 for (
int i = 0; i < numBlockRows; ++i)
2979 for (
int j = 0; j < numBlockCols; ++j)
2981 if (csr_blocks(i, j) != NULL)
2983 const int nrows = csr_blocks(i, j)->num_rows;
2984 const double cij = blockCoeff ? (*blockCoeff)(i, j) : 1.0;
2985 #if MFEM_HYPRE_VERSION >= 21600
2986 const bool usingBigJ = (csr_blocks(i, j)->big_j != NULL);
2989 for (
int k = 0; k < nrows; ++k)
2991 const int rowg = rowOffsets[i] + k;
2992 const int nnz_k = csr_blocks(i,j)->i[k+1]-csr_blocks(i,j)->i[k];
2993 const int osk = csr_blocks(i, j)->i[k];
2995 for (
int l = 0; l < nnz_k; ++l)
2998 #if MFEM_HYPRE_VERSION >= 21600
2999 const HYPRE_Int bcol = usingBigJ ?
3000 csr_blocks(i, j)->big_j[osk + l] :
3001 csr_blocks(i, j)->j[osk + l];
3003 const HYPRE_Int bcol = csr_blocks(i, j)->j[osk + l];
3007 const auto &offs = blockColProcOffsets[j];
3008 const int bcolproc =
3009 std::upper_bound(offs.begin() + 1, offs.end(), bcol)
3012 opJ[opI[rowg] + cnt[rowg]] = procColOffsets[bcolproc] +
3013 procBlockColOffsets[bcolproc][j]
3015 - blockColProcOffsets[j][bcolproc];
3016 data[opI[rowg] + cnt[rowg]] = cij * csr_blocks(i, j)->data[osk + l];
3024 for (
int i = 0; i < numBlockRows; ++i)
3026 for (
int j = 0; j < numBlockCols; ++j)
3028 if (csr_blocks(i, j) != NULL)
3030 hypre_CSRMatrixDestroy(csr_blocks(i, j));
3035 std::vector<HYPRE_BigInt> rowStarts2(2);
3036 rowStarts2[0] = first_loc_row;
3037 rowStarts2[1] = first_loc_row + all_num_loc_rows[rank];
3039 std::vector<HYPRE_BigInt> colStarts2(2);
3040 colStarts2[0] = first_loc_col;
3041 colStarts2[1] = first_loc_col + all_num_loc_cols[rank];
3043 MFEM_VERIFY(HYPRE_AssumedPartitionCheck(),
3044 "only 'assumed partition' mode is supported");
3046 return new HypreParMatrix(comm, num_loc_rows, glob_nrows, glob_ncols,
3047 opI.data(), opJ.data(),
3073 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
3074 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
3076 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(u));
3077 double *r_data = hypre_VectorData(hypre_ParVectorLocalVector(r));
3079 for (
int i = 0; i < N; i++)
3082 hypre_ParVectorCopy(f, r);
3083 hypre_ParCSRMatrixMatvec(-1.0, A, u, 1.0, r);
3086 (0 == (i % 2)) ? coef = lambda : coef =
mu;
3088 for (HYPRE_Int j = 0; j < num_rows; j++)
3090 u_data[j] += coef*r_data[j] / max_eig;
3106 hypre_ParVector *x0,
3107 hypre_ParVector *x1,
3108 hypre_ParVector *x2,
3109 hypre_ParVector *x3)
3112 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
3113 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
3115 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(u));
3117 double *x0_data = hypre_VectorData(hypre_ParVectorLocalVector(x0));
3118 double *x1_data = hypre_VectorData(hypre_ParVectorLocalVector(x1));
3119 double *x2_data = hypre_VectorData(hypre_ParVectorLocalVector(x2));
3120 double *x3_data = hypre_VectorData(hypre_ParVectorLocalVector(x3));
3122 hypre_ParVectorCopy(u, x0);
3125 hypre_ParVectorCopy(f, x1);
3126 hypre_ParCSRMatrixMatvec(-1.0, A, x0, 1.0, x1);
3128 for (HYPRE_Int i = 0; i < num_rows; i++)
3130 x1_data[i] /= -max_eig;
3134 for (HYPRE_Int i = 0; i < num_rows; i++)
3136 x1_data[i] = x0_data[i] -x1_data[i];
3140 for (HYPRE_Int i = 0; i < num_rows; i++)
3142 x3_data[i] = fir_coeffs[0]*x0_data[i] +fir_coeffs[1]*x1_data[i];
3145 for (
int n = 2; n <= poly_order; n++)
3148 hypre_ParVectorCopy(f, x2);
3149 hypre_ParCSRMatrixMatvec(-1.0, A, x1, 1.0, x2);
3151 for (HYPRE_Int i = 0; i < num_rows; i++)
3153 x2_data[i] /= -max_eig;
3161 for (HYPRE_Int i = 0; i < num_rows; i++)
3163 x2_data[i] = (x1_data[i]-x0_data[i]) +(x1_data[i]-2*x2_data[i]);
3164 x3_data[i] += fir_coeffs[n]*x2_data[i];
3165 x0_data[i] = x1_data[i];
3166 x1_data[i] = x2_data[i];
3170 for (HYPRE_Int i = 0; i < num_rows; i++)
3172 u_data[i] = x3_data[i];
3193 B =
X =
V =
Z = NULL;
3201 int relax_times_,
double relax_weight_,
3202 double omega_,
int poly_order_,
3203 double poly_fraction_,
int eig_est_cg_iter_)
3215 B =
X =
V =
Z = NULL;
3226 type =
static_cast<int>(type_);
3237 int eig_est_cg_iter_)
3254 double a = -1,
b, c;
3255 if (!strcmp(name,
"Rectangular")) { a = 1.0,
b = 0.0, c = 0.0; }
3256 if (!strcmp(name,
"Hanning")) { a = 0.5,
b = 0.5, c = 0.0; }
3257 if (!strcmp(name,
"Hamming")) { a = 0.54,
b = 0.46, c = 0.0; }
3258 if (!strcmp(name,
"Blackman")) { a = 0.42,
b = 0.50, c = 0.08; }
3261 mfem_error(
"HypreSmoother::SetWindowByName : name not recognized!");
3279 mfem_error(
"HypreSmoother::SetOperator : not HypreParMatrix!");
3286 if (
B) {
delete B; }
3287 if (
X) {
delete X; }
3288 if (
V) {
delete V; }
3289 if (
Z) {
delete Z; }
3311 A->
Mult(ones, diag);
3319 #if defined(HYPRE_USING_GPU)
3321 MFEM_GPU_FORALL(i,
height,
3323 d_l1_norms[i] = std::abs(d_l1_norms[i]);
3326 for (
int i = 0; i <
height; i++)
3343 #if MFEM_HYPRE_VERSION <= 22200
3352 else if (
type == 1001 ||
type == 1002)
3362 #if MFEM_HYPRE_VERSION <= 22200
3395 double* window_coeffs =
new double[
poly_order+1];
3396 double* cheby_coeffs =
new double[
poly_order+1];
3404 window_coeffs[i] = a + b*
cos(t) +c*
cos(2*t);
3408 double theta_pb =
acos(1.0 -0.5*k_pb);
3410 cheby_coeffs[0] = (theta_pb +
sigma)/M_PI;
3413 double t = i*(theta_pb+
sigma);
3414 cheby_coeffs[i] = 2.0*
sin(t)/(i*M_PI);
3419 fir_coeffs[i] = window_coeffs[i]*cheby_coeffs[i];
3422 delete[] window_coeffs;
3423 delete[] cheby_coeffs;
3430 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
3443 HYPRE_ParCSRDiagScale(NULL, *
A, b, x);
3450 hypre_ParVectorSetConstantValues(x, 0.0);
3471 else if (
type == 1002)
3485 int hypre_type =
type;
3487 if (
type == 5) { hypre_type = 1; }
3491 hypre_ParCSRRelax(*
A, b, hypre_type,
3498 hypre_ParCSRRelax(*
A, b, hypre_type,
3513 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
3520 A -> GetGlobalNumRows(),
3522 A -> GetRowStarts());
3524 A -> GetGlobalNumCols(),
3526 A -> GetColStarts());
3564 if (!xshallow) { x = *
X; }
3574 mfem_error(
"HypreSmoother::MultTranspose (...) : undefined!\n");
3580 if (
B) {
delete B; }
3581 if (
X) {
delete X; }
3582 if (
V) {
delete V; }
3583 if (
Z) {
delete Z; }
3592 if (
X0) {
delete X0; }
3593 if (
X1) {
delete X1; }
3608 :
Solver(A_->Height(), A_->Width())
3623 mfem_error(
"HypreSolver::Mult (...) : HypreParMatrix A is missing");
3630 hypre_ParVectorSetConstantValues(x, 0.0);
3642 { MFEM_WARNING(
"Error during setup! Error code: " << err_flag); }
3646 MFEM_VERIFY(!err_flag,
"Error during setup! Error code: " << err_flag);
3648 hypre_error_flag = 0;
3656 { MFEM_WARNING(
"Error during solve! Error code: " << err_flag); }
3660 MFEM_VERIFY(!err_flag,
"Error during solve! Error code: " << err_flag);
3662 hypre_error_flag = 0;
3672 mfem_error(
"HypreSolver::Mult (...) : HypreParMatrix A is missing");
3679 A -> GetGlobalNumRows(),
3681 A -> GetRowStarts());
3683 A -> GetGlobalNumCols(),
3685 A -> GetColStarts());
3723 if (!xshallow) { x = *
X; }
3728 if (
B) {
delete B; }
3729 if (
X) {
delete X; }
3739 HYPRE_ParCSRPCGCreate(comm, &pcg_solver);
3748 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
3750 HYPRE_ParCSRPCGCreate(comm, &pcg_solver);
3756 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3777 HYPRE_PCGSetTol(pcg_solver, tol);
3782 HYPRE_PCGSetAbsoluteTol(pcg_solver, atol);
3787 HYPRE_PCGSetMaxIter(pcg_solver, max_iter);
3792 HYPRE_PCGSetLogging(pcg_solver, logging);
3797 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_lvl);
3802 precond = &precond_;
3804 HYPRE_ParCSRPCGSetPrecond(pcg_solver,
3812 HYPRE_PCGSetTwoNorm(pcg_solver, 1);
3813 if (res_frequency > 0)
3815 HYPRE_PCGSetRecomputeResidualP(pcg_solver, res_frequency);
3819 HYPRE_PCGSetResidualTol(pcg_solver, rtol);
3826 HYPRE_Int time_index = 0;
3827 HYPRE_Int num_iterations;
3828 double final_res_norm;
3830 HYPRE_Int print_level;
3832 HYPRE_PCGGetPrintLevel(pcg_solver, &print_level);
3833 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level%3);
3835 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
3840 hypre_ParVectorSetConstantValues(x, 0.0);
3848 if (print_level > 0 && print_level < 3)
3850 time_index = hypre_InitializeTiming(
"PCG Setup");
3851 hypre_BeginTiming(time_index);
3854 HYPRE_ParCSRPCGSetup(pcg_solver, *
A, b, x);
3857 if (print_level > 0 && print_level < 3)
3859 hypre_EndTiming(time_index);
3860 hypre_PrintTiming(
"Setup phase times", comm);
3861 hypre_FinalizeTiming(time_index);
3862 hypre_ClearTiming();
3866 if (print_level > 0 && print_level < 3)
3868 time_index = hypre_InitializeTiming(
"PCG Solve");
3869 hypre_BeginTiming(time_index);
3872 HYPRE_ParCSRPCGSolve(pcg_solver, *
A, b, x);
3874 if (print_level > 0)
3876 if (print_level < 3)
3878 hypre_EndTiming(time_index);
3879 hypre_PrintTiming(
"Solve phase times", comm);
3880 hypre_FinalizeTiming(time_index);
3881 hypre_ClearTiming();
3884 HYPRE_ParCSRPCGGetNumIterations(pcg_solver, &num_iterations);
3885 HYPRE_ParCSRPCGGetFinalRelativeResidualNorm(pcg_solver,
3888 MPI_Comm_rank(comm, &myid);
3892 mfem::out <<
"PCG Iterations = " << num_iterations << endl
3893 <<
"Final PCG Relative Residual Norm = " << final_res_norm
3897 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level);
3902 HYPRE_ParCSRPCGDestroy(pcg_solver);
3910 HYPRE_ParCSRGMRESCreate(comm, &gmres_solver);
3911 SetDefaultOptions();
3921 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
3923 HYPRE_ParCSRGMRESCreate(comm, &gmres_solver);
3924 SetDefaultOptions();
3927 void HypreGMRES::SetDefaultOptions()
3933 HYPRE_ParCSRGMRESSetKDim(gmres_solver, k_dim);
3934 HYPRE_ParCSRGMRESSetMaxIter(gmres_solver, max_iter);
3935 HYPRE_ParCSRGMRESSetTol(gmres_solver, tol);
3941 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3962 HYPRE_GMRESSetTol(gmres_solver, tol);
3967 HYPRE_GMRESSetAbsoluteTol(gmres_solver, tol);
3972 HYPRE_GMRESSetMaxIter(gmres_solver, max_iter);
3977 HYPRE_GMRESSetKDim(gmres_solver, k_dim);
3982 HYPRE_GMRESSetLogging(gmres_solver, logging);
3987 HYPRE_GMRESSetPrintLevel(gmres_solver, print_lvl);
3992 precond = &precond_;
3994 HYPRE_ParCSRGMRESSetPrecond(gmres_solver,
4003 HYPRE_Int time_index = 0;
4004 HYPRE_Int num_iterations;
4005 double final_res_norm;
4007 HYPRE_Int print_level;
4009 HYPRE_GMRESGetPrintLevel(gmres_solver, &print_level);
4011 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
4016 hypre_ParVectorSetConstantValues(x, 0.0);
4024 if (print_level > 0)
4026 time_index = hypre_InitializeTiming(
"GMRES Setup");
4027 hypre_BeginTiming(time_index);
4030 HYPRE_ParCSRGMRESSetup(gmres_solver, *
A, b, x);
4033 if (print_level > 0)
4035 hypre_EndTiming(time_index);
4036 hypre_PrintTiming(
"Setup phase times", comm);
4037 hypre_FinalizeTiming(time_index);
4038 hypre_ClearTiming();
4042 if (print_level > 0)
4044 time_index = hypre_InitializeTiming(
"GMRES Solve");
4045 hypre_BeginTiming(time_index);
4048 HYPRE_ParCSRGMRESSolve(gmres_solver, *
A, b, x);
4050 if (print_level > 0)
4052 hypre_EndTiming(time_index);
4053 hypre_PrintTiming(
"Solve phase times", comm);
4054 hypre_FinalizeTiming(time_index);
4055 hypre_ClearTiming();
4057 HYPRE_ParCSRGMRESGetNumIterations(gmres_solver, &num_iterations);
4058 HYPRE_ParCSRGMRESGetFinalRelativeResidualNorm(gmres_solver,
4061 MPI_Comm_rank(comm, &myid);
4065 mfem::out <<
"GMRES Iterations = " << num_iterations << endl
4066 <<
"Final GMRES Relative Residual Norm = " << final_res_norm
4074 HYPRE_ParCSRGMRESDestroy(gmres_solver);
4082 HYPRE_ParCSRFlexGMRESCreate(comm, &fgmres_solver);
4083 SetDefaultOptions();
4093 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
4095 HYPRE_ParCSRFlexGMRESCreate(comm, &fgmres_solver);
4096 SetDefaultOptions();
4099 void HypreFGMRES::SetDefaultOptions()
4105 HYPRE_ParCSRFlexGMRESSetKDim(fgmres_solver, k_dim);
4106 HYPRE_ParCSRFlexGMRESSetMaxIter(fgmres_solver, max_iter);
4107 HYPRE_ParCSRFlexGMRESSetTol(fgmres_solver, tol);
4113 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4134 HYPRE_ParCSRFlexGMRESSetTol(fgmres_solver, tol);
4139 HYPRE_ParCSRFlexGMRESSetMaxIter(fgmres_solver, max_iter);
4144 HYPRE_ParCSRFlexGMRESSetKDim(fgmres_solver, k_dim);
4149 HYPRE_ParCSRFlexGMRESSetLogging(fgmres_solver, logging);
4154 HYPRE_ParCSRFlexGMRESSetPrintLevel(fgmres_solver, print_lvl);
4159 precond = &precond_;
4160 HYPRE_ParCSRFlexGMRESSetPrecond(fgmres_solver,
4169 HYPRE_Int time_index = 0;
4170 HYPRE_Int num_iterations;
4171 double final_res_norm;
4173 HYPRE_Int print_level;
4175 HYPRE_FlexGMRESGetPrintLevel(fgmres_solver, &print_level);
4177 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
4182 hypre_ParVectorSetConstantValues(x, 0.0);
4190 if (print_level > 0)
4192 time_index = hypre_InitializeTiming(
"FGMRES Setup");
4193 hypre_BeginTiming(time_index);
4196 HYPRE_ParCSRFlexGMRESSetup(fgmres_solver, *
A, b, x);
4199 if (print_level > 0)
4201 hypre_EndTiming(time_index);
4202 hypre_PrintTiming(
"Setup phase times", comm);
4203 hypre_FinalizeTiming(time_index);
4204 hypre_ClearTiming();
4208 if (print_level > 0)
4210 time_index = hypre_InitializeTiming(
"FGMRES Solve");
4211 hypre_BeginTiming(time_index);
4214 HYPRE_ParCSRFlexGMRESSolve(fgmres_solver, *
A, b, x);
4216 if (print_level > 0)
4218 hypre_EndTiming(time_index);
4219 hypre_PrintTiming(
"Solve phase times", comm);
4220 hypre_FinalizeTiming(time_index);
4221 hypre_ClearTiming();
4223 HYPRE_ParCSRFlexGMRESGetNumIterations(fgmres_solver, &num_iterations);
4224 HYPRE_ParCSRFlexGMRESGetFinalRelativeResidualNorm(fgmres_solver,
4227 MPI_Comm_rank(comm, &myid);
4231 mfem::out <<
"FGMRES Iterations = " << num_iterations << endl
4232 <<
"Final FGMRES Relative Residual Norm = " << final_res_norm
4240 HYPRE_ParCSRFlexGMRESDestroy(fgmres_solver);
4247 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4264 HYPRE_ParaSailsCreate(comm, &sai_precond);
4265 SetDefaultOptions();
4272 HYPRE_ParCSRMatrixGetComm(A, &comm);
4274 HYPRE_ParaSailsCreate(comm, &sai_precond);
4275 SetDefaultOptions();
4278 void HypreParaSails::SetDefaultOptions()
4280 int sai_max_levels = 1;
4281 double sai_threshold = 0.1;
4282 double sai_filter = 0.1;
4284 double sai_loadbal = 0.0;
4286 int sai_logging = 1;
4288 HYPRE_ParaSailsSetParams(sai_precond, sai_threshold, sai_max_levels);
4289 HYPRE_ParaSailsSetFilter(sai_precond, sai_filter);
4290 HYPRE_ParaSailsSetSym(sai_precond, sai_sym);
4291 HYPRE_ParaSailsSetLoadbal(sai_precond, sai_loadbal);
4292 HYPRE_ParaSailsSetReuse(sai_precond, sai_reuse);
4293 HYPRE_ParaSailsSetLogging(sai_precond, sai_logging);
4296 void HypreParaSails::ResetSAIPrecond(MPI_Comm comm)
4298 HYPRE_Int sai_max_levels;
4299 HYPRE_Real sai_threshold;
4300 HYPRE_Real sai_filter;
4302 HYPRE_Real sai_loadbal;
4303 HYPRE_Int sai_reuse;
4304 HYPRE_Int sai_logging;
4307 HYPRE_ParaSailsGetNlevels(sai_precond, &sai_max_levels);
4308 HYPRE_ParaSailsGetThresh(sai_precond, &sai_threshold);
4309 HYPRE_ParaSailsGetFilter(sai_precond, &sai_filter);
4310 HYPRE_ParaSailsGetSym(sai_precond, &sai_sym);
4311 HYPRE_ParaSailsGetLoadbal(sai_precond, &sai_loadbal);
4312 HYPRE_ParaSailsGetReuse(sai_precond, &sai_reuse);
4313 HYPRE_ParaSailsGetLogging(sai_precond, &sai_logging);
4315 HYPRE_ParaSailsDestroy(sai_precond);
4316 HYPRE_ParaSailsCreate(comm, &sai_precond);
4318 HYPRE_ParaSailsSetParams(sai_precond, sai_threshold, sai_max_levels);
4319 HYPRE_ParaSailsSetFilter(sai_precond, sai_filter);
4320 HYPRE_ParaSailsSetSym(sai_precond, sai_sym);
4321 HYPRE_ParaSailsSetLoadbal(sai_precond, sai_loadbal);
4322 HYPRE_ParaSailsSetReuse(sai_precond, sai_reuse);
4323 HYPRE_ParaSailsSetLogging(sai_precond, sai_logging);
4329 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4334 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
4335 ResetSAIPrecond(comm);
4352 HYPRE_ParaSailsSetSym(sai_precond, sym);
4357 HYPRE_ParaSailsDestroy(sai_precond);
4363 HYPRE_EuclidCreate(comm, &euc_precond);
4364 SetDefaultOptions();
4371 HYPRE_ParCSRMatrixGetComm(A, &comm);
4373 HYPRE_EuclidCreate(comm, &euc_precond);
4374 SetDefaultOptions();
4377 void HypreEuclid::SetDefaultOptions()
4385 HYPRE_EuclidSetLevel(euc_precond, euc_level);
4386 HYPRE_EuclidSetStats(euc_precond, euc_stats);
4387 HYPRE_EuclidSetMem(euc_precond, euc_mem);
4388 HYPRE_EuclidSetBJ(euc_precond, euc_bj);
4389 HYPRE_EuclidSetRowScale(euc_precond, euc_ro_sc);
4392 void HypreEuclid::ResetEuclidPrecond(MPI_Comm comm)
4396 HYPRE_EuclidDestroy(euc_precond);
4397 HYPRE_EuclidCreate(comm, &euc_precond);
4399 SetDefaultOptions();
4405 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4410 HYPRE_ParCSRMatrixGetComm(*new_A, &comm);
4411 ResetEuclidPrecond(comm);
4428 HYPRE_EuclidDestroy(euc_precond);
4432 #if MFEM_HYPRE_VERSION >= 21900
4435 HYPRE_ILUCreate(&ilu_precond);
4436 SetDefaultOptions();
4439 void HypreILU::SetDefaultOptions()
4442 HYPRE_Int ilu_type = 0;
4443 HYPRE_ILUSetType(ilu_precond, ilu_type);
4446 HYPRE_Int max_iter = 1;
4447 HYPRE_ILUSetMaxIter(ilu_precond, max_iter);
4450 HYPRE_Real tol = 0.0;
4451 HYPRE_ILUSetTol(ilu_precond, tol);
4454 HYPRE_Int lev_fill = 1;
4455 HYPRE_ILUSetLevelOfFill(ilu_precond, lev_fill);
4458 HYPRE_Int reorder_type = 1;
4459 HYPRE_ILUSetLocalReordering(ilu_precond, reorder_type);
4462 HYPRE_Int print_level = 0;
4463 HYPRE_ILUSetPrintLevel(ilu_precond, print_level);
4466 void HypreILU::ResetILUPrecond()
4470 HYPRE_ILUDestroy(ilu_precond);
4472 HYPRE_ILUCreate(&ilu_precond);
4473 SetDefaultOptions();
4478 HYPRE_ILUSetLevelOfFill(ilu_precond, lev_fill);
4483 HYPRE_ILUSetPrintLevel(ilu_precond, print_level);
4489 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4491 if (
A) { ResetILUPrecond(); }
4507 HYPRE_ILUDestroy(ilu_precond);
4514 HYPRE_BoomerAMGCreate(&amg_precond);
4515 SetDefaultOptions();
4520 HYPRE_BoomerAMGCreate(&amg_precond);
4521 SetDefaultOptions();
4524 void HypreBoomerAMG::SetDefaultOptions()
4526 #if !defined(HYPRE_USING_GPU)
4528 int coarsen_type = 10;
4530 double theta = 0.25;
4533 int interp_type = 6;
4538 int relax_sweeps = 1;
4541 int print_level = 1;
4542 int max_levels = 25;
4545 int coarsen_type = 8;
4547 double theta = 0.25;
4550 int interp_type = 6;
4554 int relax_type = 18;
4555 int relax_sweeps = 1;
4558 int print_level = 1;
4559 int max_levels = 25;
4562 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
4563 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
4564 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
4567 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
4568 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
4569 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
4570 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
4571 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
4572 HYPRE_BoomerAMGSetMaxLevels(amg_precond, max_levels);
4575 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
4576 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
4579 void HypreBoomerAMG::ResetAMGPrecond()
4581 HYPRE_Int coarsen_type;
4582 HYPRE_Int agg_levels;
4583 HYPRE_Int relax_type;
4584 HYPRE_Int relax_sweeps;
4586 HYPRE_Int interp_type;
4588 HYPRE_Int print_level;
4589 HYPRE_Int max_levels;
4591 HYPRE_Int nrbms = rbms.
Size();
4593 HYPRE_Int nodal_diag;
4594 HYPRE_Int relax_coarse;
4595 HYPRE_Int interp_vec_variant;
4597 HYPRE_Int smooth_interp_vectors;
4598 HYPRE_Int interp_refine;
4600 hypre_ParAMGData *amg_data = (hypre_ParAMGData *)amg_precond;
4603 HYPRE_BoomerAMGGetCoarsenType(amg_precond, &coarsen_type);
4604 agg_levels = hypre_ParAMGDataAggNumLevels(amg_data);
4605 relax_type = hypre_ParAMGDataUserRelaxType(amg_data);
4606 relax_sweeps = hypre_ParAMGDataUserNumSweeps(amg_data);
4607 HYPRE_BoomerAMGGetStrongThreshold(amg_precond, &theta);
4608 hypre_BoomerAMGGetInterpType(amg_precond, &interp_type);
4609 HYPRE_BoomerAMGGetPMaxElmts(amg_precond, &Pmax);
4610 HYPRE_BoomerAMGGetPrintLevel(amg_precond, &print_level);
4611 HYPRE_BoomerAMGGetMaxLevels(amg_precond, &max_levels);
4612 HYPRE_BoomerAMGGetNumFunctions(amg_precond, &dim);
4615 nodal = hypre_ParAMGDataNodal(amg_data);
4616 nodal_diag = hypre_ParAMGDataNodalDiag(amg_data);
4617 HYPRE_BoomerAMGGetCycleRelaxType(amg_precond, &relax_coarse, 3);
4618 interp_vec_variant = hypre_ParAMGInterpVecVariant(amg_data);
4619 q_max = hypre_ParAMGInterpVecQMax(amg_data);
4620 smooth_interp_vectors = hypre_ParAMGSmoothInterpVectors(amg_data);
4621 interp_refine = hypre_ParAMGInterpRefine(amg_data);
4624 HYPRE_BoomerAMGDestroy(amg_precond);
4625 HYPRE_BoomerAMGCreate(&amg_precond);
4627 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
4628 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
4629 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
4630 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
4631 HYPRE_BoomerAMGSetMaxLevels(amg_precond, max_levels);
4632 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
4633 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
4634 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
4635 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
4636 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
4637 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
4638 HYPRE_BoomerAMGSetNumFunctions(amg_precond, dim);
4641 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
4642 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
4643 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
4644 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
4645 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
4646 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
4647 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
4649 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
4656 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4658 if (
A) { ResetAMGPrecond(); }
4674 HYPRE_BoomerAMGSetNumFunctions(amg_precond, dim);
4682 HYPRE_Int *h_mapping = mfem_hypre_CTAlloc_host(HYPRE_Int,
height);
4684 MFEM_VERIFY(
height % dim == 0,
"Ordering does not work as claimed!");
4686 for (
int i = 0; i <
dim; ++i)
4688 for (
int j = 0; j < h_nnodes; ++j)
4697 #if defined(hypre_IntArrayData) && defined(HYPRE_USING_GPU)
4698 HYPRE_Int *mapping = mfem_hypre_CTAlloc(HYPRE_Int,
height);
4699 hypre_TMemcpy(mapping, h_mapping, HYPRE_Int,
height,
4700 HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
4701 mfem_hypre_TFree_host(h_mapping);
4703 HYPRE_Int *mapping = h_mapping;
4708 HYPRE_BoomerAMGSetDofFunc(amg_precond, mapping);
4712 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, 0);
4713 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, 0.5);
4719 y = 0.0; y(0) = x(1); y(1) = -x(0);
4721 static void func_ryz(
const Vector &x, Vector &y)
4723 y = 0.0; y(1) = x(2); y(2) = -x(1);
4725 static void func_rzx(
const Vector &x, Vector &y)
4727 y = 0.0; y(2) = x(0); y(0) = -x(2);
4730 void HypreBoomerAMG::RecomputeRBMs()
4733 Array<HypreParVector*> gf_rbms;
4736 for (
int i = 0; i < rbms.
Size(); i++)
4738 HYPRE_ParVectorDestroy(rbms[i]);
4745 VectorFunctionCoefficient coeff_rxy(2, func_rxy);
4747 ParGridFunction rbms_rxy(fespace);
4748 rbms_rxy.ProjectCoefficient(coeff_rxy);
4751 gf_rbms.SetSize(nrbms);
4753 rbms_rxy.GetTrueDofs(*gf_rbms[0]);
4759 VectorFunctionCoefficient coeff_rxy(3, func_rxy);
4760 VectorFunctionCoefficient coeff_ryz(3, func_ryz);
4761 VectorFunctionCoefficient coeff_rzx(3, func_rzx);
4763 ParGridFunction rbms_rxy(fespace);
4764 ParGridFunction rbms_ryz(fespace);
4765 ParGridFunction rbms_rzx(fespace);
4766 rbms_rxy.ProjectCoefficient(coeff_rxy);
4767 rbms_ryz.ProjectCoefficient(coeff_ryz);
4768 rbms_rzx.ProjectCoefficient(coeff_rzx);
4771 gf_rbms.SetSize(nrbms);
4775 rbms_rxy.GetTrueDofs(*gf_rbms[0]);
4776 rbms_ryz.GetTrueDofs(*gf_rbms[1]);
4777 rbms_rzx.GetTrueDofs(*gf_rbms[2]);
4786 for (
int i = 0; i < nrbms; i++)
4788 rbms[i] = gf_rbms[i]->StealParVector();
4795 #ifdef HYPRE_USING_GPU
4796 MFEM_ABORT(
"this method is not supported in hypre built with GPU support");
4800 this->fespace = fespace_;
4810 int relax_coarse = 8;
4813 int interp_vec_variant = 2;
4815 int smooth_interp_vectors = 1;
4819 int interp_refine = 1;
4821 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
4822 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
4823 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
4824 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
4825 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
4826 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
4827 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
4830 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
4839 #if MFEM_HYPRE_VERSION >= 21800
4842 const std::string &prerelax,
4843 const std::string &postrelax)
4847 int interp_type = 100;
4848 int relax_type = 10;
4849 int coarsen_type = 6;
4850 double strength_tolC = 0.1;
4851 double strength_tolR = 0.01;
4852 double filter_tolR = 0.0;
4853 double filterA_tol = 0.0;
4856 int ns_down, ns_up, ns_coarse;
4859 ns_down = prerelax.length();
4860 ns_up = postrelax.length();
4864 HYPRE_Int **grid_relax_points = mfem_hypre_TAlloc(HYPRE_Int*, 4);
4865 grid_relax_points[0] = NULL;
4866 grid_relax_points[1] = mfem_hypre_TAlloc(HYPRE_Int, ns_down);
4867 grid_relax_points[2] = mfem_hypre_TAlloc(HYPRE_Int, ns_up);
4868 grid_relax_points[3] = mfem_hypre_TAlloc(HYPRE_Int, 1);
4869 grid_relax_points[3][0] = 0;
4872 for (
int i = 0; i<ns_down; i++)
4874 if (prerelax[i] ==
'F')
4876 grid_relax_points[1][i] = -1;
4878 else if (prerelax[i] ==
'C')
4880 grid_relax_points[1][i] = 1;
4882 else if (prerelax[i] ==
'A')
4884 grid_relax_points[1][i] = 0;
4889 for (
int i = 0; i<ns_up; i++)
4891 if (postrelax[i] ==
'F')
4893 grid_relax_points[2][i] = -1;
4895 else if (postrelax[i] ==
'C')
4897 grid_relax_points[2][i] = 1;
4899 else if (postrelax[i] ==
'A')
4901 grid_relax_points[2][i] = 0;
4905 HYPRE_BoomerAMGSetRestriction(amg_precond, distanceR);
4907 HYPRE_BoomerAMGSetGridRelaxPoints(amg_precond, grid_relax_points);
4909 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
4914 HYPRE_BoomerAMGSetSabs(amg_precond, Sabs);
4917 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
4920 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, 0);
4922 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, strength_tolC);
4926 HYPRE_BoomerAMGSetStrongThresholdR(amg_precond, strength_tolR);
4927 HYPRE_BoomerAMGSetFilterThresholdR(amg_precond, filter_tolR);
4930 if (relax_type > -1)
4932 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
4937 HYPRE_BoomerAMGSetCycleNumSweeps(amg_precond, ns_coarse, 3);
4938 HYPRE_BoomerAMGSetCycleNumSweeps(amg_precond, ns_down, 1);
4939 HYPRE_BoomerAMGSetCycleNumSweeps(amg_precond, ns_up, 2);
4941 HYPRE_BoomerAMGSetADropTol(amg_precond, filterA_tol);
4943 HYPRE_BoomerAMGSetADropType(amg_precond, -1);
4951 for (
int i = 0; i < rbms.
Size(); i++)
4953 HYPRE_ParVectorDestroy(rbms[i]);
4956 HYPRE_BoomerAMGDestroy(amg_precond);
4972 int cycle_type = 13;
4974 double rlx_weight = 1.0;
4975 double rlx_omega = 1.0;
4976 #if !defined(HYPRE_USING_GPU)
4977 int amg_coarsen_type = 10;
4978 int amg_agg_levels = 1;
4979 int amg_rlx_type = 8;
4981 double theta = 0.25;
4982 int amg_interp_type = 6;
4985 int amg_coarsen_type = 8;
4986 int amg_agg_levels = 0;
4987 int amg_rlx_type = 18;
4989 double theta = 0.25;
4990 int amg_interp_type = 6;
4998 bool trace_space, rt_trace_space;
5002 trace_space = trace_space || rt_trace_space;
5005 if (edge_fespace->
GetNE() > 0)
5011 if (dim == 2) { p++; }
5022 nd_tr_fec =
new ND_Trace_FECollection(p, dim);
5023 edge_fespace =
new ParFiniteElementSpace(pmesh, nd_tr_fec);
5026 HYPRE_AMSCreate(&ams);
5028 HYPRE_AMSSetDimension(ams, sdim);
5029 HYPRE_AMSSetTol(ams, 0.0);
5030 HYPRE_AMSSetMaxIter(ams, 1);
5031 HYPRE_AMSSetCycleType(ams, cycle_type);
5032 HYPRE_AMSSetPrintLevel(ams, 1);
5035 FiniteElementCollection *vert_fec;
5038 vert_fec =
new H1_Trace_FECollection(p, dim);
5042 vert_fec =
new H1_FECollection(p, dim);
5044 ParFiniteElementSpace *vert_fespace =
new ParFiniteElementSpace(pmesh,
5048 if (p == 1 && pmesh->GetNodes() == NULL)
5050 ParGridFunction x_coord(vert_fespace);
5051 ParGridFunction y_coord(vert_fespace);
5052 ParGridFunction z_coord(vert_fespace);
5054 for (
int i = 0; i < pmesh->GetNV(); i++)
5056 coord = pmesh -> GetVertex(i);
5057 x_coord(i) = coord[0];
5058 if (sdim >= 2) { y_coord(i) = coord[1]; }
5059 if (sdim == 3) { z_coord(i) = coord[2]; }
5061 x = x_coord.ParallelProject();
5068 y = y_coord.ParallelProject();
5073 z = z_coord.ParallelProject();
5077 HYPRE_AMSSetCoordinateVectors(ams,
5078 x ? (HYPRE_ParVector)(*x) : NULL,
5079 y ? (HYPRE_ParVector)(*y) : NULL,
5080 z ? (HYPRE_ParVector)(*z) : NULL);
5090 ParDiscreteLinearOperator *grad;
5091 grad =
new ParDiscreteLinearOperator(vert_fespace, edge_fespace);
5094 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
5098 grad->AddDomainInterpolator(
new GradientInterpolator);
5102 G = grad->ParallelAssemble();
5103 HYPRE_AMSSetDiscreteGradient(ams, *G);
5107 Pi = Pix = Piy = Piz = NULL;
5108 if (p > 1 || pmesh->GetNodes() != NULL)
5110 ParFiniteElementSpace *vert_fespace_d
5113 ParDiscreteLinearOperator *id_ND;
5114 id_ND =
new ParDiscreteLinearOperator(vert_fespace_d, edge_fespace);
5117 id_ND->AddTraceFaceInterpolator(
new IdentityInterpolator);
5121 id_ND->AddDomainInterpolator(
new IdentityInterpolator);
5126 if (cycle_type < 10)
5128 Pi = id_ND->ParallelAssemble();
5132 Array2D<HypreParMatrix *> Pi_blocks;
5133 id_ND->GetParBlocks(Pi_blocks);
5134 Pix = Pi_blocks(0,0);
5135 if (sdim >= 2) { Piy = Pi_blocks(0,1); }
5136 if (sdim == 3) { Piz = Pi_blocks(0,2); }
5141 HYPRE_ParCSRMatrix HY_Pi = (Pi) ? (HYPRE_ParCSRMatrix) *Pi : NULL;
5142 HYPRE_ParCSRMatrix HY_Pix = (Pix) ? (HYPRE_ParCSRMatrix) *Pix : NULL;
5143 HYPRE_ParCSRMatrix HY_Piy = (Piy) ? (HYPRE_ParCSRMatrix) *Piy : NULL;
5144 HYPRE_ParCSRMatrix HY_Piz = (Piz) ? (HYPRE_ParCSRMatrix) *Piz : NULL;
5145 HYPRE_AMSSetInterpolations(ams, HY_Pi, HY_Pix, HY_Piy, HY_Piz);
5147 delete vert_fespace_d;
5150 delete vert_fespace;
5155 delete edge_fespace;
5160 HYPRE_AMSSetSmoothingOptions(ams, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
5161 HYPRE_AMSSetAlphaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
5162 theta, amg_interp_type, amg_Pmax);
5163 HYPRE_AMSSetBetaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
5164 theta, amg_interp_type, amg_Pmax);
5166 HYPRE_AMSSetAlphaAMGCoarseRelaxType(ams, amg_rlx_type);
5167 HYPRE_AMSSetBetaAMGCoarseRelaxType(ams, amg_rlx_type);
5179 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
5196 HYPRE_AMSDestroy(ams);
5211 HYPRE_AMSSetPrintLevel(ams, print_lvl);
5227 int cycle_type = 11;
5229 double rlx_weight = 1.0;
5230 double rlx_omega = 1.0;
5231 #if !defined(HYPRE_USING_GPU)
5233 int amg_coarsen_type = 10;
5234 int amg_agg_levels = 1;
5235 int amg_rlx_type = 8;
5236 double theta = 0.25;
5237 int amg_interp_type = 6;
5241 int amg_coarsen_type = 8;
5242 int amg_agg_levels = 0;
5243 int amg_rlx_type = 18;
5244 double theta = 0.25;
5245 int amg_interp_type = 6;
5248 int ams_cycle_type = 14;
5254 if (face_fespace->
GetNE() > 0)
5267 HYPRE_ADSCreate(&ads);
5269 HYPRE_ADSSetTol(ads, 0.0);
5270 HYPRE_ADSSetMaxIter(ads, 1);
5271 HYPRE_ADSSetCycleType(ads, cycle_type);
5272 HYPRE_ADSSetPrintLevel(ads, 1);
5275 ParMesh *pmesh = (ParMesh *) face_fespace->
GetMesh();
5276 FiniteElementCollection *vert_fec, *edge_fec;
5279 vert_fec =
new H1_Trace_FECollection(p, 3);
5280 edge_fec =
new ND_Trace_FECollection(p, 3);
5284 vert_fec =
new H1_FECollection(p, 3);
5285 edge_fec =
new ND_FECollection(p, 3);
5288 ParFiniteElementSpace *vert_fespace =
new ParFiniteElementSpace(pmesh,
5290 ParFiniteElementSpace *edge_fespace =
new ParFiniteElementSpace(pmesh,
5294 if (p == 1 && pmesh->GetNodes() == NULL)
5296 ParGridFunction x_coord(vert_fespace);
5297 ParGridFunction y_coord(vert_fespace);
5298 ParGridFunction z_coord(vert_fespace);
5300 for (
int i = 0; i < pmesh->GetNV(); i++)
5302 coord = pmesh -> GetVertex(i);
5303 x_coord(i) = coord[0];
5304 y_coord(i) = coord[1];
5305 z_coord(i) = coord[2];
5307 x = x_coord.ParallelProject();
5308 y = y_coord.ParallelProject();
5309 z = z_coord.ParallelProject();
5313 HYPRE_ADSSetCoordinateVectors(ads, *x, *y, *z);
5323 ParDiscreteLinearOperator *curl;
5324 curl =
new ParDiscreteLinearOperator(edge_fespace, face_fespace);
5327 curl->AddTraceFaceInterpolator(
new CurlInterpolator);
5331 curl->AddDomainInterpolator(
new CurlInterpolator);
5335 C = curl->ParallelAssemble();
5337 HYPRE_ADSSetDiscreteCurl(ads, *C);
5341 ParDiscreteLinearOperator *grad;
5342 grad =
new ParDiscreteLinearOperator(vert_fespace, edge_fespace);
5345 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
5349 grad->AddDomainInterpolator(
new GradientInterpolator);
5353 G = grad->ParallelAssemble();
5356 HYPRE_ADSSetDiscreteGradient(ads, *G);
5360 RT_Pi = RT_Pix = RT_Piy = RT_Piz = NULL;
5361 ND_Pi = ND_Pix = ND_Piy = ND_Piz = NULL;
5362 if (p > 1 || pmesh->GetNodes() != NULL)
5364 ParFiniteElementSpace *vert_fespace_d
5367 ParDiscreteLinearOperator *id_ND;
5368 id_ND =
new ParDiscreteLinearOperator(vert_fespace_d, edge_fespace);
5371 id_ND->AddTraceFaceInterpolator(
new IdentityInterpolator);
5375 id_ND->AddDomainInterpolator(
new IdentityInterpolator);
5380 if (ams_cycle_type < 10)
5382 ND_Pi = id_ND->ParallelAssemble();
5388 Array2D<HypreParMatrix *> ND_Pi_blocks;
5389 id_ND->GetParBlocks(ND_Pi_blocks);
5390 ND_Pix = ND_Pi_blocks(0,0);
5391 ND_Piy = ND_Pi_blocks(0,1);
5392 ND_Piz = ND_Pi_blocks(0,2);
5397 ParDiscreteLinearOperator *id_RT;
5398 id_RT =
new ParDiscreteLinearOperator(vert_fespace_d, face_fespace);
5401 id_RT->AddTraceFaceInterpolator(
new NormalInterpolator);
5405 id_RT->AddDomainInterpolator(
new IdentityInterpolator);
5410 if (cycle_type < 10)
5412 RT_Pi = id_RT->ParallelAssemble();
5417 Array2D<HypreParMatrix *> RT_Pi_blocks;
5418 id_RT->GetParBlocks(RT_Pi_blocks);
5419 RT_Pix = RT_Pi_blocks(0,0);
5420 RT_Piy = RT_Pi_blocks(0,1);
5421 RT_Piz = RT_Pi_blocks(0,2);
5426 HYPRE_ParCSRMatrix HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz;
5427 HY_RT_Pi = (RT_Pi) ? (HYPRE_ParCSRMatrix) *RT_Pi : NULL;
5428 HY_RT_Pix = (RT_Pix) ? (HYPRE_ParCSRMatrix) *RT_Pix : NULL;
5429 HY_RT_Piy = (RT_Piy) ? (HYPRE_ParCSRMatrix) *RT_Piy : NULL;
5430 HY_RT_Piz = (RT_Piz) ? (HYPRE_ParCSRMatrix) *RT_Piz : NULL;
5431 HYPRE_ParCSRMatrix HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz;
5432 HY_ND_Pi = (ND_Pi) ? (HYPRE_ParCSRMatrix) *ND_Pi : NULL;
5433 HY_ND_Pix = (ND_Pix) ? (HYPRE_ParCSRMatrix) *ND_Pix : NULL;
5434 HY_ND_Piy = (ND_Piy) ? (HYPRE_ParCSRMatrix) *ND_Piy : NULL;
5435 HY_ND_Piz = (ND_Piz) ? (HYPRE_ParCSRMatrix) *ND_Piz : NULL;
5436 HYPRE_ADSSetInterpolations(ads,
5437 HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz,
5438 HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz);
5440 delete vert_fespace_d;
5444 delete vert_fespace;
5446 delete edge_fespace;
5449 HYPRE_ADSSetSmoothingOptions(ads, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
5450 HYPRE_ADSSetAMGOptions(ads, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
5451 theta, amg_interp_type, amg_Pmax);
5452 HYPRE_ADSSetAMSOptions(ads, ams_cycle_type, amg_coarsen_type, amg_agg_levels,
5453 amg_rlx_type, theta, amg_interp_type, amg_Pmax);
5465 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
5482 HYPRE_ADSDestroy(ads);
5504 HYPRE_ADSSetPrintLevel(ads, print_lvl);
5507 HypreLOBPCG::HypreMultiVector::HypreMultiVector(
int n,
HypreParVector & v,
5508 mv_InterfaceInterpreter & interpreter)
5512 mv_ptr = mv_MultiVectorCreateFromSampleVector(&interpreter, nv,
5513 (HYPRE_ParVector)v);
5515 HYPRE_ParVector* vecs = NULL;
5517 mv_TempMultiVector* tmp =
5518 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
5519 vecs = (HYPRE_ParVector*)(tmp -> vector);
5522 hpv =
new HypreParVector*[nv];
5523 for (
int i=0; i<nv; i++)
5525 hpv[i] =
new HypreParVector(vecs[i]);
5529 HypreLOBPCG::HypreMultiVector::~HypreMultiVector()
5533 for (
int i=0; i<nv; i++)
5540 mv_MultiVectorDestroy(mv_ptr);
5544 HypreLOBPCG::HypreMultiVector::Randomize(HYPRE_Int seed_)
5546 mv_MultiVectorSetRandom(mv_ptr, seed_);
5550 HypreLOBPCG::HypreMultiVector::GetVector(
unsigned int i)
5552 MFEM_ASSERT((
int)i < nv,
"index out of range");
5558 HypreLOBPCG::HypreMultiVector::StealVectors()
5560 HypreParVector ** hpv_ret = hpv;
5564 mv_TempMultiVector * mv_tmp =
5565 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
5567 mv_tmp->ownsVectors = 0;
5569 for (
int i=0; i<nv; i++)
5571 hpv_ret[i]->SetOwnership(1);
5589 MPI_Comm_size(comm,&numProcs);
5590 MPI_Comm_rank(comm,&myid);
5592 HYPRE_ParCSRSetupInterpreter(&interpreter);
5593 HYPRE_ParCSRSetupMatvec(&matvec_fn);
5594 HYPRE_LOBPCGCreate(&interpreter, &matvec_fn, &lobpcg_solver);
5603 HYPRE_LOBPCGDestroy(lobpcg_solver);
5609 HYPRE_LOBPCGSetTol(lobpcg_solver, tol);
5615 #if MFEM_HYPRE_VERSION >= 21101
5616 HYPRE_LOBPCGSetRTol(lobpcg_solver, rel_tol);
5618 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
5625 HYPRE_LOBPCGSetMaxIter(lobpcg_solver, max_iter);
5633 HYPRE_LOBPCGSetPrintLevel(lobpcg_solver, logging);
5640 HYPRE_LOBPCGSetPrecondUsageMode(lobpcg_solver, pcg_mode);
5646 HYPRE_LOBPCGSetPrecond(lobpcg_solver,
5647 (HYPRE_PtrToSolverFcn)this->PrecondSolve,
5648 (HYPRE_PtrToSolverFcn)this->PrecondSetup,
5649 (HYPRE_Solver)&precond);
5657 if (HYPRE_AssumedPartitionCheck())
5661 MPI_Scan(&locSize, &part[1], 1, HYPRE_MPI_BIG_INT, MPI_SUM, comm);
5663 part[0] = part[1] - locSize;
5665 MPI_Allreduce(&locSize, &glbSize, 1, HYPRE_MPI_BIG_INT, MPI_SUM, comm);
5671 MPI_Allgather(&locSize, 1, HYPRE_MPI_BIG_INT,
5672 &part[1], 1, HYPRE_MPI_BIG_INT, comm);
5675 for (
int i=0; i<numProcs; i++)
5677 part[i+1] += part[i];
5680 glbSize = part[numProcs];
5689 const bool is_device_ptr =
true;
5692 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
5693 matvec_fn.Matvec = this->OperatorMatvec;
5694 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
5696 HYPRE_LOBPCGSetup(lobpcg_solver,(HYPRE_Matrix)&A,NULL,NULL);
5702 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
5703 matvec_fn.Matvec = this->OperatorMatvec;
5704 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
5706 HYPRE_LOBPCGSetupB(lobpcg_solver,(HYPRE_Matrix)&M,NULL);
5715 for (
int i=0; i<nev; i++)
5717 eigs[i] = eigenvalues[i];
5724 return multi_vec->GetVector(i);
5731 if ( multi_vec == NULL )
5733 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::SetInitialVectors()");
5735 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
5739 for (
int i=0; i < min(num_vecs,nev); i++)
5741 multi_vec->GetVector(i) = *vecs[i];
5745 for (
int i=min(num_vecs,nev); i < nev; i++)
5747 multi_vec->GetVector(i).Randomize(seed);
5751 if ( subSpaceProj != NULL )
5754 y = multi_vec->GetVector(0);
5756 for (
int i=1; i<nev; i++)
5758 subSpaceProj->
Mult(multi_vec->GetVector(i),
5759 multi_vec->GetVector(i-1));
5761 subSpaceProj->
Mult(y,
5762 multi_vec->GetVector(nev-1));
5770 if ( multi_vec == NULL )
5772 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::Solve()");
5774 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
5775 multi_vec->Randomize(seed);
5777 if ( subSpaceProj != NULL )
5780 y = multi_vec->GetVector(0);
5782 for (
int i=1; i<nev; i++)
5784 subSpaceProj->
Mult(multi_vec->GetVector(i),
5785 multi_vec->GetVector(i-1));
5787 subSpaceProj->
Mult(y, multi_vec->GetVector(nev-1));
5798 HYPRE_LOBPCGSolve(lobpcg_solver, NULL, *multi_vec, eigenvalues);
5802 HypreLOBPCG::OperatorMatvecCreate(
void *A,
5809 return ( matvec_data );
5813 HypreLOBPCG::OperatorMatvec(
void *matvec_data,
5814 HYPRE_Complex
alpha,
5820 MFEM_VERIFY(alpha == 1.0 && beta == 0.0,
"values not supported");
5822 Operator *Aop = (Operator*)A;
5824 hypre_ParVector * xPar = (hypre_ParVector *)x;
5825 hypre_ParVector * yPar = (hypre_ParVector *)y;
5827 HypreParVector xVec(xPar);
5828 HypreParVector yVec(yPar);
5830 Aop->Mult( xVec, yVec );
5834 yVec.HypreReadWrite();
5840 HypreLOBPCG::OperatorMatvecDestroy(
void *matvec_data )
5846 HypreLOBPCG::PrecondSolve(
void *solver,
5851 Solver *
PC = (Solver*)solver;
5853 hypre_ParVector * bPar = (hypre_ParVector *)b;
5854 hypre_ParVector * xPar = (hypre_ParVector *)x;
5856 HypreParVector bVec(bPar);
5857 HypreParVector xVec(xPar);
5859 PC->Mult( bVec, xVec );
5863 xVec.HypreReadWrite();
5869 HypreLOBPCG::PrecondSetup(
void *solver,
5887 MPI_Comm_size(comm,&numProcs);
5888 MPI_Comm_rank(comm,&myid);
5890 HYPRE_AMECreate(&ame_solver);
5891 HYPRE_AMESetPrintLevel(ame_solver, 0);
5898 mfem_hypre_TFree_host(multi_vec);
5903 for (
int i=0; i<nev; i++)
5905 delete eigenvectors[i];
5908 delete [] eigenvectors;
5912 mfem_hypre_TFree_host(eigenvalues);
5915 HYPRE_AMEDestroy(ame_solver);
5923 HYPRE_AMESetBlockSize(ame_solver, nev);
5929 HYPRE_AMESetTol(ame_solver, tol);
5935 #if MFEM_HYPRE_VERSION >= 21101
5936 HYPRE_AMESetRTol(ame_solver, rel_tol);
5938 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
5945 HYPRE_AMESetMaxIter(ame_solver, max_iter);
5953 HYPRE_AMESetPrintLevel(ame_solver, logging);
5960 ams_precond = &precond;
5968 HYPRE_Solver ams_precond_ptr = (HYPRE_Solver)*ams_precond;
5970 ams_precond->
SetupFcn()(*ams_precond,A,NULL,NULL);
5972 HYPRE_AMESetAMSSolver(ame_solver, ams_precond_ptr);
5975 HYPRE_AMESetup(ame_solver);
5981 HYPRE_ParCSRMatrix parcsr_M = M;
5982 HYPRE_AMESetMassMatrix(ame_solver,(HYPRE_ParCSRMatrix)parcsr_M);
5988 HYPRE_AMESolve(ame_solver);
5991 HYPRE_AMEGetEigenvalues(ame_solver,&eigenvalues);
5994 HYPRE_AMEGetEigenvectors(ame_solver,&multi_vec);
6001 eigs.
SetSize(nev); eigs = -1.0;
6004 for (
int i=0; i<nev; i++)
6006 eigs[i] = eigenvalues[i];
6011 HypreAME::createDummyVectors()
const
6014 for (
int i=0; i<nev; i++)
6021 const HypreParVector &
6024 if ( eigenvectors == NULL )
6026 this->createDummyVectors();
6029 return *eigenvectors[i];
6035 if ( eigenvectors == NULL )
6037 this->createDummyVectors();
6042 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.
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.
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...
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
void SetPrintLevel(int print_lvl)
ParMesh * GetParMesh() const
void SetMassMatrix(const HypreParMatrix &M)
HypreParMatrix * RAP(const HypreParMatrix *A, const HypreParMatrix *P)
Returns the matrix P^t * A * P.
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.
HYPRE_BigInt GlobalSize() const
Returns the global number of rows.
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.
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.
HypreILU()
Constructor; sets the default options.
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
T * Write(MemoryClass mc, int size)
Get write-only access to the memory with the given MemoryClass.
HypreAMS(ParFiniteElementSpace *edge_fespace)
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)
FDualNumber< tbase > acos(const FDualNumber< tbase > &f)
acos([dual number])
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
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)
MPI_Comm GetComm() const
MPI communicator.
void ScaleRows(const Vector &s)
Scale the local row i by s(i).
virtual MFEM_DEPRECATED N_Vector ToNVector()
(DEPRECATED) Return a new wrapper SUNDIALS N_Vector of type SUNDIALS_NVEC_PARALLEL.
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.
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.
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.
int GetNE() const
Returns number of elements in the mesh.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void SetSymmetry(int sym)
virtual ~HypreParaSails()
int GetFaceOrder(int face, int variant=0) const
Returns the polynomial degree of the i'th face finite element.
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)
Mesh * GetMesh() const
Returns the mesh.
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)
Arbitrary order H(curl)-trace finite elements defined on the interface between mesh elements (faces...
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.
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.
HypreParMatrix * A
The linear system matrix.
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)
FDualNumber< tbase > cos(const FDualNumber< tbase > &f)
cos([dual number])
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.
FDualNumber< tbase > pow(const FDualNumber< tbase > &a, const FDualNumber< tbase > &b)
pow([dual number],[dual number])
void SetSOROptions(double relax_weight, double omega)
Set SOR-related parameters.
int SpaceDimension() const
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...
FDualNumber< tbase > sin(const FDualNumber< tbase > &f)
sin([dual number])
MemoryType GetDeviceMemoryType() const
Return the device MemoryType of the Memory object. If the device MemoryType is not set...
int NumRows() const
Get the number of rows (size of output) of the Operator. Synonym with Height().
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
void HostRead() const
Update the internal hypre_ParCSRMatrix object, A, to be on host.
MemoryType
Memory types supported by MFEM.
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 HypreReadWrite()
Prepare the HypreParVector for read and write access in hypre's device memory space, HYPRE_MEMORY_DEVICE.
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)
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.
FDualNumber< tbase > sqrt(const FDualNumber< tbase > &f)
sqrt([dual number])
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.
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.
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)
const FiniteElementCollection * FEColl() const
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
Arbitrary order "H^{-1/2}-conforming" face finite elements defined on the interface between mesh elem...
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 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.
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.
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.