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