12 #include "../config/config.hpp"
17 #include "../fem/fem.hpp"
27 #if MFEM_HYPRE_VERSION < 21400
29 #define mfem_hypre_TAlloc(type, size) hypre_TAlloc(type, size)
30 #define mfem_hypre_CTAlloc(type, size) hypre_CTAlloc(type, size)
31 #define mfem_hypre_TFree(ptr) hypre_TFree(ptr)
33 #else // MFEM_HYPRE_VERSION >= 21400
35 #define mfem_hypre_TAlloc(type, size) \
36 hypre_TAlloc(type, size, HYPRE_MEMORY_HOST)
37 #define mfem_hypre_CTAlloc(type, size) \
38 hypre_CTAlloc(type, size, HYPRE_MEMORY_HOST)
39 #define mfem_hypre_TFree(ptr) hypre_TFree(ptr, HYPRE_MEMORY_HOST)
71 #endif // #if MFEM_HYPRE_VERSION < 21400
78 template<
typename TargetT,
typename SourceT>
79 static TargetT *DuplicateAs(
const SourceT *array,
int size,
80 bool cplusplus =
true)
82 TargetT *target_array = cplusplus ?
new TargetT[size]
83 : mfem_hypre_TAlloc(TargetT, size);
84 for (
int i = 0; i < size; i++)
86 target_array[i] = array[i];
91 inline void HypreParVector::_SetDataAndSize_()
93 SetDataAndSize(hypre_VectorData(hypre_ParVectorLocalVector(x)),
95 hypre_VectorSize(hypre_ParVectorLocalVector(x))));
98 HypreParVector::HypreParVector(MPI_Comm comm, HYPRE_Int glob_size,
101 x = hypre_ParVectorCreate(comm,glob_size,col);
102 hypre_ParVectorInitialize(x);
103 hypre_ParVectorSetPartitioningOwner(x,0);
105 hypre_ParVectorSetDataOwner(x,1);
106 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
112 double *_data, HYPRE_Int *col) :
Vector()
114 x = hypre_ParVectorCreate(comm,glob_size,col);
115 hypre_ParVectorSetDataOwner(x,1);
116 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),0);
117 hypre_ParVectorSetPartitioningOwner(x,0);
119 hypre_VectorData(hypre_ParVectorLocalVector(x)) = &tmp;
122 hypre_ParVectorInitialize(x);
124 hypre_VectorData(hypre_ParVectorLocalVector(x)) = _data;
131 x = hypre_ParVectorCreate(y.x -> comm, y.x -> global_size,
132 y.x -> partitioning);
133 hypre_ParVectorInitialize(x);
134 hypre_ParVectorSetPartitioningOwner(x,0);
135 hypre_ParVectorSetDataOwner(x,1);
136 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
146 x = hypre_ParVectorInDomainOf(const_cast<HypreParMatrix&>(A));
150 x = hypre_ParVectorInRangeOf(const_cast<HypreParMatrix&>(A));
158 x = (hypre_ParVector *) y;
167 hypre_ParVectorInitialize(x);
168 hypre_ParVectorSetPartitioningOwner(x,0);
170 hypre_ParVectorSetDataOwner(x,1);
171 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
178 hypre_Vector *hv = hypre_ParVectorToVectorAll(*
this);
181 hypre_SeqVectorSetDataOwner(hv,0);
182 hypre_SeqVectorDestroy(hv);
188 hypre_ParVectorSetConstantValues(x,d);
195 if (size != y.
Size())
201 for (
int i = 0; i <
size; i++)
210 hypre_VectorData(hypre_ParVectorLocalVector(x)) = _data;
216 return hypre_ParVectorSetRandomValues(x,seed);
221 hypre_ParVectorPrint(x,fname);
228 hypre_ParVectorDestroy(x);
232 #ifdef MFEM_USE_SUNDIALS
235 #define SUNFALSE FALSE
240 MFEM_ASSERT(nv && N_VGetVectorID(nv) == SUNDIALS_NVEC_PARHYP,
242 N_VectorContent_ParHyp nv_c = (N_VectorContent_ParHyp)(nv->content);
243 MFEM_ASSERT(nv_c->own_parvector == SUNFALSE,
"invalid N_Vector");
244 nv_c->local_length = x->local_vector->size;
245 nv_c->global_length = x->global_size;
246 nv_c->comm = x->comm;
250 #endif // MFEM_USE_SUNDIALS
255 return hypre_ParVectorInnerProd(*x, *y);
260 return hypre_ParVectorInnerProd(x, y);
269 double loc_norm = vec.
Norml1();
270 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
274 double loc_norm = vec*vec;
275 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
281 for (
int i = 0; i < vec.
Size(); i++)
283 sum += pow(fabs(vec(i)), p);
285 MPI_Allreduce(&sum, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
286 norm = pow(norm, 1.0/p);
291 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_MAX, comm);
297 void HypreParMatrix::Init()
301 diagOwner = offdOwner = colMapOwner = -1;
311 char HypreParMatrix::CopyCSR(
SparseMatrix *csr, hypre_CSRMatrix *hypre_csr)
313 hypre_CSRMatrixData(hypre_csr) = csr->
GetData();
315 hypre_CSRMatrixI(hypre_csr) = csr->
GetI();
316 hypre_CSRMatrixJ(hypre_csr) = csr->
GetJ();
320 hypre_CSRMatrixI(hypre_csr) =
321 DuplicateAs<HYPRE_Int>(csr->
GetI(), csr->
Height()+1);
322 hypre_CSRMatrixJ(hypre_csr) =
329 char HypreParMatrix::CopyBoolCSR(Table *bool_csr, hypre_CSRMatrix *hypre_csr)
331 int nnz = bool_csr->Size_of_connections();
332 double *data =
new double[nnz];
333 for (
int i = 0; i < nnz; i++)
337 hypre_CSRMatrixData(hypre_csr) = data;
339 hypre_CSRMatrixI(hypre_csr) = bool_csr->GetI();
340 hypre_CSRMatrixJ(hypre_csr) = bool_csr->GetJ();
344 hypre_CSRMatrixI(hypre_csr) =
345 DuplicateAs<HYPRE_Int>(bool_csr->GetI(), bool_csr->Size()+1);
346 hypre_CSRMatrixJ(hypre_csr) =
347 DuplicateAs<HYPRE_Int>(bool_csr->GetJ(), nnz);
353 void HypreParMatrix::CopyCSR_J(hypre_CSRMatrix *hypre_csr,
int *J)
355 HYPRE_Int nnz = hypre_CSRMatrixNumNonzeros(hypre_csr);
356 for (HYPRE_Int j = 0; j < nnz; j++)
358 J[j] = int(hypre_CSRMatrixJ(hypre_csr)[j]);
365 :
Operator(diag->Height(), diag->Width())
368 A = hypre_ParCSRMatrixCreate(comm, glob_size, glob_size, row_starts,
370 hypre_ParCSRMatrixSetDataOwner(A,1);
371 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
372 hypre_ParCSRMatrixSetColStartsOwner(A,0);
374 hypre_CSRMatrixSetDataOwner(A->diag,0);
375 diagOwner = CopyCSR(diag, A->diag);
376 hypre_CSRMatrixSetRownnz(A->diag);
378 hypre_CSRMatrixSetDataOwner(A->offd,1);
379 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
386 hypre_ParCSRMatrixSetNumNonzeros(A);
389 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
391 CopyCSR_J(A->diag, diag->
GetJ());
394 hypre_MatvecCommPkgCreate(A);
399 HYPRE_Int global_num_rows,
400 HYPRE_Int global_num_cols,
401 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
403 :
Operator(diag->Height(), diag->Width())
406 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
407 row_starts, col_starts,
409 hypre_ParCSRMatrixSetDataOwner(A,1);
410 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
411 hypre_ParCSRMatrixSetColStartsOwner(A,0);
413 hypre_CSRMatrixSetDataOwner(A->diag,0);
414 diagOwner = CopyCSR(diag, A->diag);
415 hypre_CSRMatrixSetRownnz(A->diag);
417 hypre_CSRMatrixSetDataOwner(A->offd,1);
418 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
420 hypre_ParCSRMatrixSetNumNonzeros(A);
423 if (row_starts == col_starts)
425 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
427 CopyCSR_J(A->diag, diag->
GetJ());
431 hypre_MatvecCommPkgCreate(A);
436 HYPRE_Int global_num_rows,
437 HYPRE_Int global_num_cols,
438 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
441 :
Operator(diag->Height(), diag->Width())
444 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
445 row_starts, col_starts,
448 hypre_ParCSRMatrixSetDataOwner(A,1);
449 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
450 hypre_ParCSRMatrixSetColStartsOwner(A,0);
452 hypre_CSRMatrixSetDataOwner(A->diag,0);
453 diagOwner = CopyCSR(diag, A->diag);
454 hypre_CSRMatrixSetRownnz(A->diag);
456 hypre_CSRMatrixSetDataOwner(A->offd,0);
457 offdOwner = CopyCSR(offd, A->offd);
458 hypre_CSRMatrixSetRownnz(A->offd);
460 hypre_ParCSRMatrixColMapOffd(A) = cmap;
464 hypre_ParCSRMatrixSetNumNonzeros(A);
467 if (row_starts == col_starts)
469 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
471 CopyCSR_J(A->diag, diag->
GetJ());
475 hypre_MatvecCommPkgCreate(A);
481 HYPRE_Int global_num_rows, HYPRE_Int global_num_cols,
482 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
483 HYPRE_Int *diag_i, HYPRE_Int *diag_j,
double *diag_data,
484 HYPRE_Int *offd_i, HYPRE_Int *offd_j,
double *offd_data,
485 HYPRE_Int offd_num_cols, HYPRE_Int *offd_col_map)
488 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
489 row_starts, col_starts, offd_num_cols, 0, 0);
490 hypre_ParCSRMatrixSetDataOwner(A,1);
491 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
492 hypre_ParCSRMatrixSetColStartsOwner(A,0);
494 HYPRE_Int local_num_rows = hypre_CSRMatrixNumRows(A->diag);
496 hypre_CSRMatrixSetDataOwner(A->diag,0);
497 hypre_CSRMatrixI(A->diag) = diag_i;
498 hypre_CSRMatrixJ(A->diag) = diag_j;
499 hypre_CSRMatrixData(A->diag) = diag_data;
500 hypre_CSRMatrixNumNonzeros(A->diag) = diag_i[local_num_rows];
501 hypre_CSRMatrixSetRownnz(A->diag);
505 hypre_CSRMatrixSetDataOwner(A->offd,0);
506 hypre_CSRMatrixI(A->offd) = offd_i;
507 hypre_CSRMatrixJ(A->offd) = offd_j;
508 hypre_CSRMatrixData(A->offd) = offd_data;
509 hypre_CSRMatrixNumNonzeros(A->offd) = offd_i[local_num_rows];
510 hypre_CSRMatrixSetRownnz(A->offd);
514 hypre_ParCSRMatrixColMapOffd(A) = offd_col_map;
518 hypre_ParCSRMatrixSetNumNonzeros(A);
521 if (row_starts == col_starts)
523 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
526 hypre_MatvecCommPkgCreate(A);
534 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
537 MFEM_ASSERT(sm_a != NULL,
"invalid input");
538 MFEM_VERIFY(!HYPRE_AssumedPartitionCheck(),
539 "this method can not be used with assumed partition");
543 hypre_CSRMatrix *csr_a;
544 csr_a = hypre_CSRMatrixCreate(sm_a ->
Height(), sm_a ->
Width(),
545 sm_a -> NumNonZeroElems());
547 hypre_CSRMatrixSetDataOwner(csr_a,0);
548 CopyCSR(sm_a, csr_a);
549 hypre_CSRMatrixSetRownnz(csr_a);
551 A = hypre_CSRMatrixToParCSRMatrix(comm, csr_a, row_starts, col_starts);
554 delete [] hypre_CSRMatrixI(csr_a);
555 delete [] hypre_CSRMatrixJ(csr_a);
557 hypre_CSRMatrixI(csr_a) = NULL;
558 hypre_CSRMatrixDestroy(csr_a);
564 if (row_starts == col_starts)
566 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
569 hypre_MatvecCommPkgCreate(A);
574 HYPRE_Int global_num_rows,
575 HYPRE_Int global_num_cols,
576 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
581 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
582 row_starts, col_starts, 0, nnz, 0);
583 hypre_ParCSRMatrixSetDataOwner(A,1);
584 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
585 hypre_ParCSRMatrixSetColStartsOwner(A,0);
587 hypre_CSRMatrixSetDataOwner(A->diag,0);
588 diagOwner = CopyBoolCSR(diag, A->diag);
589 hypre_CSRMatrixSetRownnz(A->diag);
591 hypre_CSRMatrixSetDataOwner(A->offd,1);
592 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Size()+1);
594 hypre_ParCSRMatrixSetNumNonzeros(A);
597 if (row_starts == col_starts)
599 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
601 CopyCSR_J(A->diag, diag->
GetJ());
605 hypre_MatvecCommPkgCreate(A);
614 HYPRE_Int *row, HYPRE_Int *col,
615 HYPRE_Int *i_diag, HYPRE_Int *j_diag,
616 HYPRE_Int *i_offd, HYPRE_Int *j_offd,
617 HYPRE_Int *cmap, HYPRE_Int cmap_size)
619 HYPRE_Int diag_nnz, offd_nnz;
622 if (HYPRE_AssumedPartitionCheck())
624 diag_nnz = i_diag[row[1]-row[0]];
625 offd_nnz = i_offd[row[1]-row[0]];
627 A = hypre_ParCSRMatrixCreate(comm, row[2], col[2], row, col,
628 cmap_size, diag_nnz, offd_nnz);
632 diag_nnz = i_diag[row[
id+1]-row[id]];
633 offd_nnz = i_offd[row[
id+1]-row[id]];
635 A = hypre_ParCSRMatrixCreate(comm, row[np], col[np], row, col,
636 cmap_size, diag_nnz, offd_nnz);
639 hypre_ParCSRMatrixSetDataOwner(A,1);
640 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
641 hypre_ParCSRMatrixSetColStartsOwner(A,0);
645 double *a_diag =
new double[diag_nnz];
646 for (i = 0; i < diag_nnz; i++)
651 double *a_offd =
new double[offd_nnz];
652 for (i = 0; i < offd_nnz; i++)
657 hypre_CSRMatrixSetDataOwner(A->diag,0);
658 hypre_CSRMatrixI(A->diag) = i_diag;
659 hypre_CSRMatrixJ(A->diag) = j_diag;
660 hypre_CSRMatrixData(A->diag) = a_diag;
661 hypre_CSRMatrixSetRownnz(A->diag);
665 hypre_CSRMatrixSetDataOwner(A->offd,0);
666 hypre_CSRMatrixI(A->offd) = i_offd;
667 hypre_CSRMatrixJ(A->offd) = j_offd;
668 hypre_CSRMatrixData(A->offd) = a_offd;
669 hypre_CSRMatrixSetRownnz(A->offd);
673 hypre_ParCSRMatrixColMapOffd(A) = cmap;
677 hypre_ParCSRMatrixSetNumNonzeros(A);
682 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
685 hypre_MatvecCommPkgCreate(A);
695 HYPRE_Int glob_ncols,
int *I, HYPRE_Int *J,
696 double *data, HYPRE_Int *rows, HYPRE_Int *cols)
702 HYPRE_Int my_col_start, my_col_end;
703 if (HYPRE_AssumedPartitionCheck())
706 my_col_start = cols[0];
707 my_col_end = cols[1];
712 MPI_Comm_rank(comm, &myid);
713 MPI_Comm_size(comm, &part_size);
715 my_col_start = cols[myid];
716 my_col_end = cols[myid+1];
720 HYPRE_Int *row_starts, *col_starts;
723 row_starts = col_starts = mfem_hypre_TAlloc(HYPRE_Int, part_size);
724 for (
int i = 0; i < part_size; i++)
726 row_starts[i] = rows[i];
731 row_starts = mfem_hypre_TAlloc(HYPRE_Int, part_size);
732 col_starts = mfem_hypre_TAlloc(HYPRE_Int, part_size);
733 for (
int i = 0; i < part_size; i++)
735 row_starts[i] = rows[i];
736 col_starts[i] = cols[i];
742 HYPRE_Int diag_nnz = 0, offd_nnz = 0, offd_num_cols = 0;
743 map<HYPRE_Int, HYPRE_Int> offd_map;
744 for (HYPRE_Int j = 0, loc_nnz = I[nrows]; j < loc_nnz; j++)
746 HYPRE_Int glob_col = J[j];
747 if (my_col_start <= glob_col && glob_col < my_col_end)
753 offd_map.insert(pair<const HYPRE_Int, HYPRE_Int>(glob_col, -1));
758 for (map<HYPRE_Int, HYPRE_Int>::iterator it = offd_map.begin();
759 it != offd_map.end(); ++it)
761 it->second = offd_num_cols++;
765 A = hypre_ParCSRMatrixCreate(comm, glob_nrows, glob_ncols,
766 row_starts, col_starts, offd_num_cols,
768 hypre_ParCSRMatrixInitialize(A);
770 HYPRE_Int *diag_i, *diag_j, *offd_i, *offd_j, *offd_col_map;
771 double *diag_data, *offd_data;
774 diag_data = A->diag->data;
777 offd_data = A->offd->data;
778 offd_col_map = A->col_map_offd;
780 diag_nnz = offd_nnz = 0;
781 for (HYPRE_Int i = 0, j = 0; i < nrows; i++)
783 diag_i[i] = diag_nnz;
784 offd_i[i] = offd_nnz;
785 for (HYPRE_Int j_end = I[i+1]; j < j_end; j++)
787 HYPRE_Int glob_col = J[j];
788 if (my_col_start <= glob_col && glob_col < my_col_end)
790 diag_j[diag_nnz] = glob_col - my_col_start;
791 diag_data[diag_nnz] = data[j];
796 offd_j[offd_nnz] = offd_map[glob_col];
797 offd_data[offd_nnz] = data[j];
802 diag_i[nrows] = diag_nnz;
803 offd_i[nrows] = offd_nnz;
804 for (map<HYPRE_Int, HYPRE_Int>::iterator it = offd_map.begin();
805 it != offd_map.end(); ++it)
807 offd_col_map[it->second] = it->first;
810 hypre_ParCSRMatrixSetNumNonzeros(A);
812 if (row_starts == col_starts)
814 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
816 hypre_MatvecCommPkgCreate(A);
837 MFEM_ASSERT(diagOwner == -1 && offdOwner == -1 && colMapOwner == -1,
"");
838 MFEM_ASSERT(ParCSROwner,
"");
839 hypre_ParCSRMatrix *R = A;
848 if (!A || hypre_ParCSRMatrixOwnsRowStarts(A) ||
849 (hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
850 hypre_ParCSRMatrixOwnsColStarts(A)))
856 if (HYPRE_AssumedPartitionCheck())
862 MPI_Comm_size(hypre_ParCSRMatrixComm(A), &row_starts_size);
866 HYPRE_Int *old_row_starts = hypre_ParCSRMatrixRowStarts(A);
867 HYPRE_Int *new_row_starts = mfem_hypre_CTAlloc(HYPRE_Int, row_starts_size);
868 for (
int i = 0; i < row_starts_size; i++)
870 new_row_starts[i] = old_row_starts[i];
873 hypre_ParCSRMatrixRowStarts(A) = new_row_starts;
874 hypre_ParCSRMatrixOwnsRowStarts(A) = 1;
876 if (hypre_ParCSRMatrixColStarts(A) == old_row_starts)
878 hypre_ParCSRMatrixColStarts(A) = new_row_starts;
879 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
885 if (!A || hypre_ParCSRMatrixOwnsColStarts(A) ||
886 (hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
887 hypre_ParCSRMatrixOwnsRowStarts(A)))
893 if (HYPRE_AssumedPartitionCheck())
899 MPI_Comm_size(hypre_ParCSRMatrixComm(A), &col_starts_size);
903 HYPRE_Int *old_col_starts = hypre_ParCSRMatrixColStarts(A);
904 HYPRE_Int *new_col_starts = mfem_hypre_CTAlloc(HYPRE_Int, col_starts_size);
905 for (
int i = 0; i < col_starts_size; i++)
907 new_col_starts[i] = old_col_starts[i];
910 hypre_ParCSRMatrixColStarts(A) = new_col_starts;
912 if (hypre_ParCSRMatrixRowStarts(A) == old_col_starts)
914 hypre_ParCSRMatrixRowStarts(A) = new_col_starts;
915 hypre_ParCSRMatrixOwnsRowStarts(A) = 1;
916 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
920 hypre_ParCSRMatrixOwnsColStarts(A) = 1;
928 for (
int j = 0; j < size; j++)
930 diag(j) = A->diag->data[A->diag->i[j]];
931 MFEM_ASSERT(A->diag->j[A->diag->i[j]] == j,
932 "the first entry in each row must be the diagonal one");
936 static void MakeWrapper(
const hypre_CSRMatrix *mat,
SparseMatrix &wrapper)
938 HYPRE_Int nr = hypre_CSRMatrixNumRows(mat);
939 HYPRE_Int nc = hypre_CSRMatrixNumCols(mat);
942 hypre_CSRMatrixJ(mat),
943 hypre_CSRMatrixData(mat),
944 nr, nc,
false,
false,
false);
946 HYPRE_Int nnz = hypre_CSRMatrixNumNonzeros(mat);
947 SparseMatrix tmp(DuplicateAs<int>(hypre_CSRMatrixI(mat), nr+1),
948 DuplicateAs<int>(hypre_CSRMatrixJ(mat), nnz),
949 hypre_CSRMatrixData(mat),
950 nr, nc,
true,
false,
false);
957 MakeWrapper(A->diag, diag);
962 MakeWrapper(A->offd, offd);
963 cmap = A->col_map_offd;
967 bool interleaved_rows,
968 bool interleaved_cols)
const
973 hypre_ParCSRMatrix **hypre_blocks =
new hypre_ParCSRMatrix*[nr * nc];
974 internal::hypre_ParCSRMatrixSplit(A, nr, nc, hypre_blocks,
975 interleaved_rows, interleaved_cols);
977 for (
int i = 0; i < nr; i++)
979 for (
int j = 0; j < nc; j++)
985 delete [] hypre_blocks;
990 hypre_ParCSRMatrix * At;
991 hypre_ParCSRMatrixTranspose(A, &At, 1);
992 hypre_ParCSRMatrixSetNumNonzeros(At);
994 hypre_MatvecCommPkgCreate(At);
1000 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(At));
1009 return hypre_ParCSRMatrixMatvec(a, A, x, b, y);
1014 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1015 <<
", expected size = " <<
Width());
1016 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1017 <<
", expected size = " <<
Height());
1025 const_cast<double*>(x_data),
1034 X->
SetData(const_cast<double*>(x_data));
1038 hypre_ParCSRMatrixMatvec(a, A, *X, b, *Y);
1042 double b,
Vector &y)
const
1044 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
1045 <<
", expected size = " <<
Height());
1046 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
1047 <<
", expected size = " <<
Width());
1061 const_cast<double*>(x_data),
1067 Y->
SetData(const_cast<double*>(x_data));
1070 hypre_ParCSRMatrixMatvecT(a, A, *Y, b, *X);
1076 return hypre_ParCSRMatrixMatvec(a, A, (hypre_ParVector *) x, b,
1077 (hypre_ParVector *) y);
1083 return hypre_ParCSRMatrixMatvecT(a, A, x, b, y);
1087 HYPRE_Int* row_starts)
const
1089 const bool assumed_partition = HYPRE_AssumedPartitionCheck();
1090 const bool row_starts_given = (row_starts != NULL);
1091 if (!row_starts_given)
1093 row_starts = hypre_ParCSRMatrixRowStarts(A);
1094 MFEM_VERIFY(D.
Height() == hypre_CSRMatrixNumRows(A->diag),
1095 "the matrix D is NOT compatible with the row starts of"
1096 " this HypreParMatrix, row_starts must be given.");
1101 if (assumed_partition)
1107 MPI_Comm_rank(
GetComm(), &offset);
1109 int local_num_rows = row_starts[offset+1]-row_starts[offset];
1110 MFEM_VERIFY(local_num_rows == D.
Height(),
"the number of rows in D is "
1111 " not compatible with the given row_starts");
1117 HYPRE_Int global_num_rows;
1118 if (assumed_partition)
1121 if (row_starts_given)
1123 global_num_rows = row_starts[2];
1130 global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
1135 MPI_Comm_size(
GetComm(), &part_size);
1136 global_num_rows = row_starts[part_size];
1140 HYPRE_Int *col_starts = hypre_ParCSRMatrixColStarts(A);
1141 HYPRE_Int *col_map_offd;
1146 GetOffd(A_offd, col_map_offd);
1154 global_num_rows, hypre_ParCSRMatrixGlobalNumCols(A),
1155 DuplicateAs<HYPRE_Int>(row_starts, part_size,
false),
1156 DuplicateAs<HYPRE_Int>(col_starts, part_size,
false),
1158 DuplicateAs<HYPRE_Int>(col_map_offd, A_offd.
Width()));
1163 #ifndef HYPRE_BIGINT
1174 hypre_ParCSRMatrixSetRowStartsOwner(DA->A, 1);
1175 hypre_ParCSRMatrixSetColStartsOwner(DA->A, 1);
1177 DA->diagOwner = DA->offdOwner = 3;
1178 DA->colMapOwner = 1;
1185 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
1190 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
1192 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
1196 double *Adiag_data = hypre_CSRMatrixData(A->diag);
1197 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
1200 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
1201 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
1204 for (
int i(0); i < size; ++i)
1207 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
1209 Adiag_data[jj] *= val;
1211 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
1213 Aoffd_data[jj] *= val;
1220 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
1225 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
1227 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
1231 double *Adiag_data = hypre_CSRMatrixData(A->diag);
1232 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
1235 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
1236 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
1239 for (
int i(0); i < size; ++i)
1244 mfem_error(
"HypreParMatrix::InvDiagScale : Division by 0");
1248 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
1250 Adiag_data[jj] *= val;
1252 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
1254 Aoffd_data[jj] *= val;
1261 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
1266 HYPRE_Int size=hypre_CSRMatrixNumRows(A->diag);
1269 double *Adiag_data = hypre_CSRMatrixData(A->diag);
1270 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
1271 for (jj = 0; jj < Adiag_i[size]; ++jj)
1273 Adiag_data[jj] *= s;
1276 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
1277 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
1278 for (jj = 0; jj < Aoffd_i[size]; ++jj)
1280 Aoffd_data[jj] *= s;
1284 static void get_sorted_rows_cols(
const Array<int> &rows_cols,
1289 for (
int i = 0; i < rows_cols.
Size(); i++)
1291 hypre_sorted[i] = rows_cols[i];
1292 if (i && rows_cols[i-1] > rows_cols[i]) { sorted =
false; }
1294 if (!sorted) { hypre_sorted.
Sort(); }
1302 hypre_CSRMatrix * csr_A;
1303 hypre_CSRMatrix * csr_A_wo_z;
1304 hypre_ParCSRMatrix * parcsr_A_ptr;
1305 HYPRE_Int * row_starts = NULL; HYPRE_Int * col_starts = NULL;
1306 HYPRE_Int row_start = -1; HYPRE_Int row_end = -1;
1307 HYPRE_Int col_start = -1; HYPRE_Int col_end = -1;
1309 comm = hypre_ParCSRMatrixComm(A);
1311 ierr += hypre_ParCSRMatrixGetLocalRange(A,
1312 &row_start,&row_end,
1313 &col_start,&col_end );
1315 row_starts = hypre_ParCSRMatrixRowStarts(A);
1316 col_starts = hypre_ParCSRMatrixColStarts(A);
1318 bool old_owns_row = hypre_ParCSRMatrixOwnsRowStarts(A);
1319 bool old_owns_col = hypre_ParCSRMatrixOwnsColStarts(A);
1320 HYPRE_Int global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
1321 HYPRE_Int global_num_cols = hypre_ParCSRMatrixGlobalNumCols(A);
1322 parcsr_A_ptr = hypre_ParCSRMatrixCreate(comm, global_num_rows,
1324 row_starts, col_starts,
1326 hypre_ParCSRMatrixOwnsRowStarts(parcsr_A_ptr) = old_owns_row;
1327 hypre_ParCSRMatrixOwnsColStarts(parcsr_A_ptr) = old_owns_col;
1328 hypre_ParCSRMatrixOwnsRowStarts(A) = 0;
1329 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
1331 csr_A = hypre_MergeDiagAndOffd(A);
1337 csr_A_wo_z = hypre_CSRMatrixDeleteZeros(csr_A,threshold);
1341 if (csr_A_wo_z == NULL)
1347 ierr += hypre_CSRMatrixDestroy(csr_A);
1353 ierr += GenerateDiagAndOffd(csr_A_wo_z,parcsr_A_ptr,
1356 ierr += hypre_CSRMatrixDestroy(csr_A_wo_z);
1358 MFEM_VERIFY(ierr == 0,
"");
1362 hypre_ParCSRMatrixSetNumNonzeros(A);
1364 if (row_starts == col_starts)
1366 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1368 hypre_MatvecCommPkgCreate(A);
1378 get_sorted_rows_cols(rows_cols, rc_sorted);
1380 internal::hypre_ParCSRMatrixEliminateAXB(
1387 get_sorted_rows_cols(rows_cols, rc_sorted);
1389 hypre_ParCSRMatrix* Ae;
1390 internal::hypre_ParCSRMatrixEliminateAAe(
1398 hypre_ParCSRMatrixPrintIJ(A,offi,offj,fname);
1406 HYPRE_Int base_i, base_j;
1407 hypre_ParCSRMatrixReadIJ(comm, fname, &base_i, &base_j, &A);
1408 hypre_ParCSRMatrixSetNumNonzeros(A);
1410 hypre_MatvecCommPkgCreate(A);
1421 HYPRE_IJMatrix A_ij;
1422 HYPRE_IJMatrixRead(fname, comm, 5555, &A_ij);
1424 HYPRE_ParCSRMatrix A_parcsr;
1425 HYPRE_IJMatrixGetObject(A_ij, (
void**) &A_parcsr);
1427 A = (hypre_ParCSRMatrix*)A_parcsr;
1429 hypre_ParCSRMatrixSetNumNonzeros(A);
1431 hypre_MatvecCommPkgCreate(A);
1439 hypre_ParCSRCommPkg *comm_pkg = A->comm_pkg;
1440 MPI_Comm comm = A->comm;
1442 const int tag = 46801;
1444 MPI_Comm_rank(comm, &myid);
1445 MPI_Comm_size(comm, &nproc);
1449 MPI_Recv(&c, 1, MPI_CHAR, myid-1, tag, comm, MPI_STATUS_IGNORE);
1453 out <<
"\nHypreParMatrix: hypre_ParCSRCommPkg:\n";
1455 out <<
"Rank " << myid <<
":\n"
1456 " number of sends = " << comm_pkg->num_sends <<
1457 " (" <<
sizeof(double)*comm_pkg->send_map_starts[comm_pkg->num_sends] <<
1459 " number of recvs = " << comm_pkg->num_recvs <<
1460 " (" <<
sizeof(
double)*comm_pkg->recv_vec_starts[comm_pkg->num_recvs] <<
1462 if (myid != nproc-1)
1465 MPI_Send(&c, 1, MPI_CHAR, myid+1, tag, comm);
1474 void HypreParMatrix::Destroy()
1476 if ( X != NULL ) {
delete X; }
1477 if ( Y != NULL ) {
delete Y; }
1479 if (A == NULL) {
return; }
1485 delete [] hypre_CSRMatrixI(A->diag);
1486 delete [] hypre_CSRMatrixJ(A->diag);
1488 hypre_CSRMatrixI(A->diag) = NULL;
1489 hypre_CSRMatrixJ(A->diag) = NULL;
1492 delete [] hypre_CSRMatrixData(A->diag);
1494 hypre_CSRMatrixData(A->diag) = NULL;
1500 delete [] hypre_CSRMatrixI(A->offd);
1501 delete [] hypre_CSRMatrixJ(A->offd);
1503 hypre_CSRMatrixI(A->offd) = NULL;
1504 hypre_CSRMatrixJ(A->offd) = NULL;
1507 delete [] hypre_CSRMatrixData(A->offd);
1509 hypre_CSRMatrixData(A->offd) = NULL;
1511 if (colMapOwner >= 0)
1513 if (colMapOwner & 1)
1515 delete [] hypre_ParCSRMatrixColMapOffd(A);
1517 hypre_ParCSRMatrixColMapOffd(A) = NULL;
1522 hypre_ParCSRMatrixDestroy(A);
1529 hypre_ParCSRMatrix *C_hypre =
1530 internal::hypre_ParCSRMatrixAdd(const_cast<HypreParMatrix &>(A),
1531 const_cast<HypreParMatrix &>(B));
1532 MFEM_VERIFY(C_hypre,
"error in hypre_ParCSRMatrixAdd");
1534 hypre_MatvecCommPkgCreate(C_hypre);
1545 hypre_ParCSRMatrix * ab;
1546 ab = hypre_ParMatmul(*A,*B);
1547 hypre_ParCSRMatrixSetNumNonzeros(ab);
1549 hypre_MatvecCommPkgCreate(ab);
1556 hypre_ParCSRMatrix * C = internal::hypre_ParCSRMatrixAdd(*A,*B);
1558 hypre_MatvecCommPkgCreate(C);
1565 HYPRE_Int P_owns_its_col_starts =
1566 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
1568 hypre_ParCSRMatrix * rap;
1569 hypre_BoomerAMGBuildCoarseOperator(*P,*A,*P,&rap);
1570 hypre_ParCSRMatrixSetNumNonzeros(rap);
1575 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
1576 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
1578 if (P_owns_its_col_starts)
1580 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
1589 HYPRE_Int P_owns_its_col_starts =
1590 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
1591 HYPRE_Int Rt_owns_its_col_starts =
1592 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*Rt));
1594 hypre_ParCSRMatrix * rap;
1595 hypre_BoomerAMGBuildCoarseOperator(*Rt,*A,*P,&rap);
1597 hypre_ParCSRMatrixSetNumNonzeros(rap);
1602 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
1603 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
1605 if (P_owns_its_col_starts)
1607 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
1609 if (Rt_owns_its_col_starts)
1611 hypre_ParCSRMatrixSetColStartsOwner(*Rt, 1);
1622 Ae.
Mult(-1.0, X, 1.0, B);
1624 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag((hypre_ParCSRMatrix *)A);
1625 double *data = hypre_CSRMatrixData(A_diag);
1626 HYPRE_Int *I = hypre_CSRMatrixI(A_diag);
1628 HYPRE_Int *J = hypre_CSRMatrixJ(A_diag);
1629 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd((hypre_ParCSRMatrix *)A);
1630 HYPRE_Int *I_offd = hypre_CSRMatrixI(A_offd);
1631 double *data_offd = hypre_CSRMatrixData(A_offd);
1634 for (
int i = 0; i < ess_dof_list.
Size(); i++)
1636 int r = ess_dof_list[i];
1637 B(r) = data[I[r]] * X(r);
1644 MFEM_ABORT(
"the diagonal entry must be the first entry in the row!");
1646 for (
int j = I[r]+1; j < I[r+1]; j++)
1650 MFEM_ABORT(
"all off-diagonal entries must be zero!");
1653 for (
int j = I_offd[r]; j < I_offd[r+1]; j++)
1655 if (data_offd[j] != 0.0)
1657 MFEM_ABORT(
"all off-diagonal entries must be zero!");
1677 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
1678 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
1680 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(u));
1681 double *r_data = hypre_VectorData(hypre_ParVectorLocalVector(r));
1683 for (
int i = 0; i < N; i++)
1686 hypre_ParVectorCopy(f, r);
1687 hypre_ParCSRMatrixMatvec(-1.0, A, u, 1.0, r);
1690 (0 == (i % 2)) ? coef = lambda : coef = mu;
1692 for (HYPRE_Int j = 0; j < num_rows; j++)
1694 u_data[j] += coef*r_data[j] / max_eig;
1710 hypre_ParVector *x0,
1711 hypre_ParVector *x1,
1712 hypre_ParVector *x2,
1713 hypre_ParVector *x3)
1716 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
1717 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
1719 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(u));
1721 double *x0_data = hypre_VectorData(hypre_ParVectorLocalVector(x0));
1722 double *x1_data = hypre_VectorData(hypre_ParVectorLocalVector(x1));
1723 double *x2_data = hypre_VectorData(hypre_ParVectorLocalVector(x2));
1724 double *x3_data = hypre_VectorData(hypre_ParVectorLocalVector(x3));
1726 hypre_ParVectorCopy(u, x0);
1729 hypre_ParVectorCopy(f, x1);
1730 hypre_ParCSRMatrixMatvec(-1.0, A, x0, 1.0, x1);
1732 for (HYPRE_Int i = 0; i < num_rows; i++)
1734 x1_data[i] /= -max_eig;
1738 for (HYPRE_Int i = 0; i < num_rows; i++)
1740 x1_data[i] = x0_data[i] -x1_data[i];
1744 for (HYPRE_Int i = 0; i < num_rows; i++)
1746 x3_data[i] = fir_coeffs[0]*x0_data[i] +fir_coeffs[1]*x1_data[i];
1749 for (
int n = 2; n <= poly_order; n++)
1752 hypre_ParVectorCopy(f, x2);
1753 hypre_ParCSRMatrixMatvec(-1.0, A, x1, 1.0, x2);
1755 for (HYPRE_Int i = 0; i < num_rows; i++)
1757 x2_data[i] /= -max_eig;
1765 for (HYPRE_Int i = 0; i < num_rows; i++)
1767 x2_data[i] = (x1_data[i]-x0_data[i]) +(x1_data[i]-2*x2_data[i]);
1768 x3_data[i] += fir_coeffs[n]*x2_data[i];
1769 x0_data[i] = x1_data[i];
1770 x1_data[i] = x2_data[i];
1774 for (HYPRE_Int i = 0; i < num_rows; i++)
1776 u_data[i] = x3_data[i];
1796 B =
X =
V =
Z = NULL;
1802 int _relax_times,
double _relax_weight,
double _omega,
1803 int _poly_order,
double _poly_fraction)
1814 B =
X =
V =
Z = NULL;
1823 type =
static_cast<int>(_type);
1849 double a = -1, b, c;
1850 if (!strcmp(name,
"Rectangular")) { a = 1.0, b = 0.0, c = 0.0; }
1851 if (!strcmp(name,
"Hanning")) { a = 0.5, b = 0.5, c = 0.0; }
1852 if (!strcmp(name,
"Hamming")) { a = 0.54, b = 0.46, c = 0.0; }
1853 if (!strcmp(name,
"Blackman")) { a = 0.42, b = 0.50, c = 0.08; }
1856 mfem_error(
"HypreSmoother::SetWindowByName : name not recognized!");
1874 mfem_error(
"HypreSmoother::SetOperator : not HypreParMatrix!");
1880 if (
B) {
delete B; }
1881 if (
X) {
delete X; }
1882 if (
V) {
delete V; }
1883 if (
Z) {
delete Z; }
1902 A->
Mult(ones, diag);
1911 for (
int i = 0; i <
height; i++)
1924 else if (
type == 1001 ||
type == 1002)
1955 double* window_coeffs =
new double[
poly_order+1];
1956 double* cheby_coeffs =
new double[
poly_order+1];
1964 window_coeffs[i] = a + b*cos(t) +c*cos(2*t);
1968 double theta_pb = acos(1.0 -0.5*k_pb);
1970 cheby_coeffs[0] = (theta_pb +
sigma)/M_PI;
1973 double t = i*(theta_pb+
sigma);
1974 cheby_coeffs[i] = 2.0*sin(t)/(i*M_PI);
1979 fir_coeffs[i] = window_coeffs[i]*cheby_coeffs[i];
1982 delete[] window_coeffs;
1983 delete[] cheby_coeffs;
1990 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
1998 HYPRE_ParCSRDiagScale(NULL, *
A, b, x);
2022 else if (
type == 1002)
2037 hypre_ParCSRRelax(*
A, b,
type,
2042 hypre_ParCSRRelax(*
A, b,
type,
2053 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
2059 A -> GetGlobalNumRows(),
2061 A -> GetRowStarts());
2063 A -> GetGlobalNumCols(),
2065 A -> GetColStarts());
2078 if (
B) {
delete B; }
2079 if (
X) {
delete X; }
2080 if (
V) {
delete V; }
2081 if (
Z) {
delete Z; }
2090 if (
X0) {
delete X0; }
2091 if (
X1) {
delete X1; }
2103 :
Solver(_A->Height(), _A->Width())
2115 mfem_error(
"HypreSolver::Mult (...) : HypreParMatrix A is missing");
2121 MFEM_VERIFY(!err,
"HypreSolver::Mult (...) : Error during setup! error code "
2131 MFEM_VERIFY(!err,
"HypreSolver::Mult (...) : Error during solve! error code "
2139 mfem_error(
"HypreSolver::Mult (...) : HypreParMatrix A is missing");
2147 A -> GetGlobalNumRows(),
2148 const_cast<double*
>(b_data),
2149 A -> GetRowStarts());
2151 A -> GetGlobalNumCols(),
2153 A -> GetColStarts());
2157 B -> SetData(const_cast<double*>(b_data));
2158 X -> SetData(x_data);
2166 if (
B) {
delete B; }
2167 if (
X) {
delete X; }
2177 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2179 HYPRE_ParCSRPCGCreate(comm, &pcg_solver);
2184 HYPRE_PCGSetTol(pcg_solver, tol);
2189 HYPRE_PCGSetMaxIter(pcg_solver, max_iter);
2194 HYPRE_PCGSetLogging(pcg_solver, logging);
2199 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_lvl);
2204 HYPRE_ParCSRPCGSetPrecond(pcg_solver,
2212 HYPRE_PCGSetTwoNorm(pcg_solver, 1);
2213 if (res_frequency > 0)
2215 HYPRE_PCGSetRecomputeResidualP(pcg_solver, res_frequency);
2219 HYPRE_PCGSetResidualTol(pcg_solver, rtol);
2226 HYPRE_Int time_index = 0;
2227 HYPRE_Int num_iterations;
2228 double final_res_norm;
2230 HYPRE_Int print_level;
2232 HYPRE_PCGGetPrintLevel(pcg_solver, &print_level);
2233 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level%3);
2235 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2239 if (print_level > 0 && print_level < 3)
2241 time_index = hypre_InitializeTiming(
"PCG Setup");
2242 hypre_BeginTiming(time_index);
2245 HYPRE_ParCSRPCGSetup(pcg_solver, *
A, b, x);
2248 if (print_level > 0 && print_level < 3)
2250 hypre_EndTiming(time_index);
2251 hypre_PrintTiming(
"Setup phase times", comm);
2252 hypre_FinalizeTiming(time_index);
2253 hypre_ClearTiming();
2257 if (print_level > 0 && print_level < 3)
2259 time_index = hypre_InitializeTiming(
"PCG Solve");
2260 hypre_BeginTiming(time_index);
2271 HYPRE_ParCSRPCGSolve(pcg_solver, *
A, b, x);
2273 if (print_level > 0)
2275 if (print_level < 3)
2277 hypre_EndTiming(time_index);
2278 hypre_PrintTiming(
"Solve phase times", comm);
2279 hypre_FinalizeTiming(time_index);
2280 hypre_ClearTiming();
2283 HYPRE_ParCSRPCGGetNumIterations(pcg_solver, &num_iterations);
2284 HYPRE_ParCSRPCGGetFinalRelativeResidualNorm(pcg_solver,
2287 MPI_Comm_rank(comm, &myid);
2291 mfem::out <<
"PCG Iterations = " << num_iterations << endl
2292 <<
"Final PCG Relative Residual Norm = " << final_res_norm
2296 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level);
2301 HYPRE_ParCSRPCGDestroy(pcg_solver);
2315 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2317 HYPRE_ParCSRGMRESCreate(comm, &gmres_solver);
2318 HYPRE_ParCSRGMRESSetKDim(gmres_solver, k_dim);
2319 HYPRE_ParCSRGMRESSetMaxIter(gmres_solver, max_iter);
2320 HYPRE_ParCSRGMRESSetTol(gmres_solver, tol);
2325 HYPRE_GMRESSetTol(gmres_solver, tol);
2330 HYPRE_GMRESSetMaxIter(gmres_solver, max_iter);
2335 HYPRE_GMRESSetKDim(gmres_solver, k_dim);
2340 HYPRE_GMRESSetLogging(gmres_solver, logging);
2345 HYPRE_GMRESSetPrintLevel(gmres_solver, print_lvl);
2350 HYPRE_ParCSRGMRESSetPrecond(gmres_solver,
2359 HYPRE_Int time_index = 0;
2360 HYPRE_Int num_iterations;
2361 double final_res_norm;
2363 HYPRE_Int print_level;
2365 HYPRE_GMRESGetPrintLevel(gmres_solver, &print_level);
2367 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2371 if (print_level > 0)
2373 time_index = hypre_InitializeTiming(
"GMRES Setup");
2374 hypre_BeginTiming(time_index);
2377 HYPRE_ParCSRGMRESSetup(gmres_solver, *
A, b, x);
2380 if (print_level > 0)
2382 hypre_EndTiming(time_index);
2383 hypre_PrintTiming(
"Setup phase times", comm);
2384 hypre_FinalizeTiming(time_index);
2385 hypre_ClearTiming();
2389 if (print_level > 0)
2391 time_index = hypre_InitializeTiming(
"GMRES Solve");
2392 hypre_BeginTiming(time_index);
2400 HYPRE_ParCSRGMRESSolve(gmres_solver, *
A, b, x);
2402 if (print_level > 0)
2404 hypre_EndTiming(time_index);
2405 hypre_PrintTiming(
"Solve phase times", comm);
2406 hypre_FinalizeTiming(time_index);
2407 hypre_ClearTiming();
2409 HYPRE_ParCSRGMRESGetNumIterations(gmres_solver, &num_iterations);
2410 HYPRE_ParCSRGMRESGetFinalRelativeResidualNorm(gmres_solver,
2413 MPI_Comm_rank(comm, &myid);
2417 mfem::out <<
"GMRES Iterations = " << num_iterations << endl
2418 <<
"Final GMRES Relative Residual Norm = " << final_res_norm
2426 HYPRE_ParCSRGMRESDestroy(gmres_solver);
2434 int sai_max_levels = 1;
2435 double sai_threshold = 0.1;
2436 double sai_filter = 0.1;
2438 double sai_loadbal = 0.0;
2440 int sai_logging = 1;
2442 HYPRE_ParCSRMatrixGetComm(A, &comm);
2444 HYPRE_ParaSailsCreate(comm, &sai_precond);
2445 HYPRE_ParaSailsSetParams(sai_precond, sai_threshold, sai_max_levels);
2446 HYPRE_ParaSailsSetFilter(sai_precond, sai_filter);
2447 HYPRE_ParaSailsSetSym(sai_precond, sai_sym);
2448 HYPRE_ParaSailsSetLoadbal(sai_precond, sai_loadbal);
2449 HYPRE_ParaSailsSetReuse(sai_precond, sai_reuse);
2450 HYPRE_ParaSailsSetLogging(sai_precond, sai_logging);
2455 HYPRE_ParaSailsSetSym(sai_precond, sym);
2460 HYPRE_ParaSailsDestroy(sai_precond);
2474 HYPRE_ParCSRMatrixGetComm(A, &comm);
2476 HYPRE_EuclidCreate(comm, &euc_precond);
2477 HYPRE_EuclidSetLevel(euc_precond, euc_level);
2478 HYPRE_EuclidSetStats(euc_precond, euc_stats);
2479 HYPRE_EuclidSetMem(euc_precond, euc_mem);
2480 HYPRE_EuclidSetBJ(euc_precond, euc_bj);
2481 HYPRE_EuclidSetRowScale(euc_precond, euc_ro_sc);
2486 HYPRE_EuclidDestroy(euc_precond);
2492 HYPRE_BoomerAMGCreate(&amg_precond);
2493 SetDefaultOptions();
2498 HYPRE_BoomerAMGCreate(&amg_precond);
2499 SetDefaultOptions();
2502 void HypreBoomerAMG::SetDefaultOptions()
2505 int coarsen_type = 10;
2507 double theta = 0.25;
2510 int interp_type = 6;
2515 int relax_sweeps = 1;
2518 int print_level = 1;
2519 int max_levels = 25;
2521 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
2522 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
2523 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
2524 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
2525 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
2526 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
2527 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
2528 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
2529 HYPRE_BoomerAMGSetMaxLevels(amg_precond, max_levels);
2532 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
2533 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
2536 void HypreBoomerAMG::ResetAMGPrecond()
2538 HYPRE_Int coarsen_type;
2539 HYPRE_Int agg_levels;
2540 HYPRE_Int relax_type;
2541 HYPRE_Int relax_sweeps;
2543 HYPRE_Int interp_type;
2545 HYPRE_Int print_level;
2547 HYPRE_Int nrbms = rbms.
Size();
2549 HYPRE_Int nodal_diag;
2550 HYPRE_Int relax_coarse;
2551 HYPRE_Int interp_vec_variant;
2553 HYPRE_Int smooth_interp_vectors;
2554 HYPRE_Int interp_refine;
2556 hypre_ParAMGData *amg_data = (hypre_ParAMGData *)amg_precond;
2559 HYPRE_BoomerAMGGetCoarsenType(amg_precond, &coarsen_type);
2560 agg_levels = hypre_ParAMGDataAggNumLevels(amg_data);
2561 relax_type = hypre_ParAMGDataUserRelaxType(amg_data);
2562 relax_sweeps = hypre_ParAMGDataUserNumSweeps(amg_data);
2563 HYPRE_BoomerAMGGetStrongThreshold(amg_precond, &theta);
2564 hypre_BoomerAMGGetInterpType(amg_precond, &interp_type);
2565 HYPRE_BoomerAMGGetPMaxElmts(amg_precond, &Pmax);
2566 HYPRE_BoomerAMGGetPrintLevel(amg_precond, &print_level);
2567 HYPRE_BoomerAMGGetNumFunctions(amg_precond, &dim);
2570 nodal = hypre_ParAMGDataNodal(amg_data);
2571 nodal_diag = hypre_ParAMGDataNodalDiag(amg_data);
2572 HYPRE_BoomerAMGGetCycleRelaxType(amg_precond, &relax_coarse, 3);
2573 interp_vec_variant = hypre_ParAMGInterpVecVariant(amg_data);
2574 q_max = hypre_ParAMGInterpVecQMax(amg_data);
2575 smooth_interp_vectors = hypre_ParAMGSmoothInterpVectors(amg_data);
2576 interp_refine = hypre_ParAMGInterpRefine(amg_data);
2579 HYPRE_BoomerAMGDestroy(amg_precond);
2580 HYPRE_BoomerAMGCreate(&amg_precond);
2582 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
2583 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
2584 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
2585 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
2586 HYPRE_BoomerAMGSetMaxLevels(amg_precond, 25);
2587 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
2588 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
2589 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
2590 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
2591 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
2592 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
2593 HYPRE_BoomerAMGSetNumFunctions(amg_precond, dim);
2596 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
2597 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
2598 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
2599 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
2600 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
2601 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
2602 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
2604 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
2611 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
2613 if (
A) { ResetAMGPrecond(); }
2627 HYPRE_BoomerAMGSetNumFunctions(amg_precond, dim);
2630 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, 0);
2631 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, 0.5);
2637 y = 0.0; y(0) = x(1); y(1) = -x(0);
2639 static void func_ryz(
const Vector &x, Vector &y)
2641 y = 0.0; y(1) = x(2); y(2) = -x(1);
2643 static void func_rzx(
const Vector &x, Vector &y)
2645 y = 0.0; y(2) = x(0); y(0) = -x(2);
2648 void HypreBoomerAMG::RecomputeRBMs()
2651 Array<HypreParVector*> gf_rbms;
2654 for (
int i = 0; i < rbms.
Size(); i++)
2656 HYPRE_ParVectorDestroy(rbms[i]);
2663 VectorFunctionCoefficient coeff_rxy(2, func_rxy);
2665 ParGridFunction rbms_rxy(fespace);
2666 rbms_rxy.ProjectCoefficient(coeff_rxy);
2669 gf_rbms.SetSize(nrbms);
2670 gf_rbms[0] = rbms_rxy.ParallelAverage();
2676 VectorFunctionCoefficient coeff_rxy(3, func_rxy);
2677 VectorFunctionCoefficient coeff_ryz(3, func_ryz);
2678 VectorFunctionCoefficient coeff_rzx(3, func_rzx);
2680 ParGridFunction rbms_rxy(fespace);
2681 ParGridFunction rbms_ryz(fespace);
2682 ParGridFunction rbms_rzx(fespace);
2683 rbms_rxy.ProjectCoefficient(coeff_rxy);
2684 rbms_ryz.ProjectCoefficient(coeff_ryz);
2685 rbms_rzx.ProjectCoefficient(coeff_rzx);
2688 gf_rbms.SetSize(nrbms);
2689 gf_rbms[0] = rbms_rxy.ParallelAverage();
2690 gf_rbms[1] = rbms_ryz.ParallelAverage();
2691 gf_rbms[2] = rbms_rzx.ParallelAverage();
2700 for (
int i = 0; i < nrbms; i++)
2702 rbms[i] = gf_rbms[i]->StealParVector();
2710 this->fespace = fespace;
2720 int relax_coarse = 8;
2723 int interp_vec_variant = 2;
2725 int smooth_interp_vectors = 1;
2729 int interp_refine = 1;
2731 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
2732 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
2733 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
2734 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
2735 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
2736 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
2737 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
2740 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
2745 for (
int i = 0; i < rbms.
Size(); i++)
2747 HYPRE_ParVectorDestroy(rbms[i]);
2750 HYPRE_BoomerAMGDestroy(amg_precond);
2757 int cycle_type = 13;
2760 double rlx_weight = 1.0;
2761 double rlx_omega = 1.0;
2762 int amg_coarsen_type = 10;
2763 int amg_agg_levels = 1;
2764 int amg_rlx_type = 8;
2765 double theta = 0.25;
2766 int amg_interp_type = 6;
2773 bool trace_space, rt_trace_space;
2777 trace_space = trace_space || rt_trace_space;
2780 if (edge_fespace->
GetNE() > 0)
2785 if (dim == 2) { p++; }
2800 HYPRE_AMSCreate(&ams);
2802 HYPRE_AMSSetDimension(ams, sdim);
2803 HYPRE_AMSSetTol(ams, 0.0);
2804 HYPRE_AMSSetMaxIter(ams, 1);
2805 HYPRE_AMSSetCycleType(ams, cycle_type);
2806 HYPRE_AMSSetPrintLevel(ams, 1);
2828 for (
int i = 0; i < pmesh->
GetNV(); i++)
2830 coord = pmesh -> GetVertex(i);
2831 x_coord(i) = coord[0];
2832 y_coord(i) = coord[1];
2833 if (sdim == 3) { z_coord(i) = coord[2]; }
2840 HYPRE_AMSSetCoordinateVectors(ams, *x, *y, NULL);
2845 HYPRE_AMSSetCoordinateVectors(ams, *x, *y, *z);
2869 HYPRE_AMSSetDiscreteGradient(ams, *G);
2873 Pi = Pix = Piy = Piz = NULL;
2892 if (cycle_type < 10)
2900 Pix = Pi_blocks(0,0);
2901 Piy = Pi_blocks(0,1);
2902 if (sdim == 3) { Piz = Pi_blocks(0,2); }
2907 HYPRE_ParCSRMatrix HY_Pi = (Pi) ? (HYPRE_ParCSRMatrix) *Pi : NULL;
2908 HYPRE_ParCSRMatrix HY_Pix = (Pix) ? (HYPRE_ParCSRMatrix) *Pix : NULL;
2909 HYPRE_ParCSRMatrix HY_Piy = (Piy) ? (HYPRE_ParCSRMatrix) *Piy : NULL;
2910 HYPRE_ParCSRMatrix HY_Piz = (Piz) ? (HYPRE_ParCSRMatrix) *Piz : NULL;
2911 HYPRE_AMSSetInterpolations(ams, HY_Pi, HY_Pix, HY_Piy, HY_Piz);
2913 delete vert_fespace_d;
2916 delete vert_fespace;
2921 delete edge_fespace;
2926 HYPRE_AMSSetSmoothingOptions(ams, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
2927 HYPRE_AMSSetAlphaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
2928 theta, amg_interp_type, amg_Pmax);
2929 HYPRE_AMSSetBetaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
2930 theta, amg_interp_type, amg_Pmax);
2935 HYPRE_AMSDestroy(ams);
2950 HYPRE_AMSSetPrintLevel(ams, print_lvl);
2956 int cycle_type = 11;
2959 double rlx_weight = 1.0;
2960 double rlx_omega = 1.0;
2961 int amg_coarsen_type = 10;
2962 int amg_agg_levels = 1;
2963 int amg_rlx_type = 8;
2964 double theta = 0.25;
2965 int amg_interp_type = 6;
2967 int ams_cycle_type = 14;
2973 if (face_fespace->
GetNE() > 0)
2985 HYPRE_ADSCreate(&ads);
2987 HYPRE_ADSSetTol(ads, 0.0);
2988 HYPRE_ADSSetMaxIter(ads, 1);
2989 HYPRE_ADSSetCycleType(ads, cycle_type);
2990 HYPRE_ADSSetPrintLevel(ads, 1);
3018 for (
int i = 0; i < pmesh->
GetNV(); i++)
3020 coord = pmesh -> GetVertex(i);
3021 x_coord(i) = coord[0];
3022 y_coord(i) = coord[1];
3023 z_coord(i) = coord[2];
3028 HYPRE_ADSSetCoordinateVectors(ads, *x, *y, *z);
3052 HYPRE_ADSSetDiscreteCurl(ads, *C);
3071 HYPRE_ADSSetDiscreteGradient(ads, *G);
3075 RT_Pi = RT_Pix = RT_Piy = RT_Piz = NULL;
3076 ND_Pi = ND_Pix = ND_Piy = ND_Piz = NULL;
3095 if (ams_cycle_type < 10)
3105 ND_Pix = ND_Pi_blocks(0,0);
3106 ND_Piy = ND_Pi_blocks(0,1);
3107 ND_Piz = ND_Pi_blocks(0,2);
3125 if (cycle_type < 10)
3134 RT_Pix = RT_Pi_blocks(0,0);
3135 RT_Piy = RT_Pi_blocks(0,1);
3136 RT_Piz = RT_Pi_blocks(0,2);
3141 HYPRE_ParCSRMatrix HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz;
3142 HY_RT_Pi = (RT_Pi) ? (HYPRE_ParCSRMatrix) *RT_Pi : NULL;
3143 HY_RT_Pix = (RT_Pix) ? (HYPRE_ParCSRMatrix) *RT_Pix : NULL;
3144 HY_RT_Piy = (RT_Piy) ? (HYPRE_ParCSRMatrix) *RT_Piy : NULL;
3145 HY_RT_Piz = (RT_Piz) ? (HYPRE_ParCSRMatrix) *RT_Piz : NULL;
3146 HYPRE_ParCSRMatrix HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz;
3147 HY_ND_Pi = (ND_Pi) ? (HYPRE_ParCSRMatrix) *ND_Pi : NULL;
3148 HY_ND_Pix = (ND_Pix) ? (HYPRE_ParCSRMatrix) *ND_Pix : NULL;
3149 HY_ND_Piy = (ND_Piy) ? (HYPRE_ParCSRMatrix) *ND_Piy : NULL;
3150 HY_ND_Piz = (ND_Piz) ? (HYPRE_ParCSRMatrix) *ND_Piz : NULL;
3151 HYPRE_ADSSetInterpolations(ads,
3152 HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz,
3153 HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz);
3155 delete vert_fespace_d;
3159 delete vert_fespace;
3161 delete edge_fespace;
3164 HYPRE_ADSSetSmoothingOptions(ads, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
3165 HYPRE_ADSSetAMGOptions(ads, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
3166 theta, amg_interp_type, amg_Pmax);
3167 HYPRE_ADSSetAMSOptions(ads, ams_cycle_type, amg_coarsen_type, amg_agg_levels,
3168 amg_rlx_type, theta, amg_interp_type, amg_Pmax);
3173 HYPRE_ADSDestroy(ads);
3195 HYPRE_ADSSetPrintLevel(ads, print_lvl);
3198 HypreLOBPCG::HypreMultiVector::HypreMultiVector(
int n,
HypreParVector & v,
3199 mv_InterfaceInterpreter & interpreter)
3203 mv_ptr = mv_MultiVectorCreateFromSampleVector(&interpreter, nv,
3204 (HYPRE_ParVector)v);
3206 HYPRE_ParVector* vecs = NULL;
3208 mv_TempMultiVector* tmp =
3209 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
3210 vecs = (HYPRE_ParVector*)(tmp -> vector);
3213 hpv =
new HypreParVector*[nv];
3214 for (
int i=0; i<nv; i++)
3216 hpv[i] =
new HypreParVector(vecs[i]);
3220 HypreLOBPCG::HypreMultiVector::~HypreMultiVector()
3224 for (
int i=0; i<nv; i++)
3231 mv_MultiVectorDestroy(mv_ptr);
3235 HypreLOBPCG::HypreMultiVector::Randomize(HYPRE_Int seed)
3237 mv_MultiVectorSetRandom(mv_ptr, seed);
3241 HypreLOBPCG::HypreMultiVector::GetVector(
unsigned int i)
3243 MFEM_ASSERT((
int)i < nv,
"index out of range");
3249 HypreLOBPCG::HypreMultiVector::StealVectors()
3251 HypreParVector ** hpv_ret = hpv;
3255 mv_TempMultiVector * mv_tmp =
3256 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
3258 mv_tmp->ownsVectors = 0;
3260 for (
int i=0; i<nv; i++)
3262 hpv_ret[i]->SetOwnership(1);
3280 MPI_Comm_size(comm,&numProcs);
3281 MPI_Comm_rank(comm,&myid);
3283 HYPRE_ParCSRSetupInterpreter(&interpreter);
3284 HYPRE_ParCSRSetupMatvec(&matvec_fn);
3285 HYPRE_LOBPCGCreate(&interpreter, &matvec_fn, &lobpcg_solver);
3294 HYPRE_LOBPCGDestroy(lobpcg_solver);
3300 HYPRE_LOBPCGSetTol(lobpcg_solver, tol);
3306 #if MFEM_HYPRE_VERSION >= 21101
3307 HYPRE_LOBPCGSetRTol(lobpcg_solver, rel_tol);
3309 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
3316 HYPRE_LOBPCGSetMaxIter(lobpcg_solver, max_iter);
3324 HYPRE_LOBPCGSetPrintLevel(lobpcg_solver, logging);
3331 HYPRE_LOBPCGSetPrecondUsageMode(lobpcg_solver, pcg_mode);
3337 HYPRE_LOBPCGSetPrecond(lobpcg_solver,
3338 (HYPRE_PtrToSolverFcn)this->PrecondSolve,
3339 (HYPRE_PtrToSolverFcn)this->PrecondSetup,
3340 (HYPRE_Solver)&precond);
3346 HYPRE_Int locSize = A.
Width();
3348 if (HYPRE_AssumedPartitionCheck())
3350 part =
new HYPRE_Int[2];
3352 MPI_Scan(&locSize, &part[1], 1, HYPRE_MPI_INT, MPI_SUM, comm);
3354 part[0] = part[1] - locSize;
3356 MPI_Allreduce(&locSize, &glbSize, 1, HYPRE_MPI_INT, MPI_SUM, comm);
3360 part =
new HYPRE_Int[numProcs+1];
3362 MPI_Allgather(&locSize, 1, HYPRE_MPI_INT,
3363 &part[1], 1, HYPRE_MPI_INT, comm);
3366 for (
int i=0; i<numProcs; i++)
3368 part[i+1] += part[i];
3371 glbSize = part[numProcs];
3382 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
3383 matvec_fn.Matvec = this->OperatorMatvec;
3384 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
3386 HYPRE_LOBPCGSetup(lobpcg_solver,(HYPRE_Matrix)&A,NULL,NULL);
3392 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
3393 matvec_fn.Matvec = this->OperatorMatvec;
3394 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
3396 HYPRE_LOBPCGSetupB(lobpcg_solver,(HYPRE_Matrix)&M,NULL);
3405 for (
int i=0; i<nev; i++)
3407 eigs[i] = eigenvalues[i];
3414 return multi_vec->GetVector(i);
3421 if ( multi_vec == NULL )
3423 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::SetInitialVectors()");
3425 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
3429 for (
int i=0; i < min(num_vecs,nev); i++)
3431 multi_vec->GetVector(i) = *vecs[i];
3435 for (
int i=min(num_vecs,nev); i < nev; i++)
3437 multi_vec->GetVector(i).Randomize(seed);
3441 if ( subSpaceProj != NULL )
3444 y = multi_vec->GetVector(0);
3446 for (
int i=1; i<nev; i++)
3448 subSpaceProj->
Mult(multi_vec->GetVector(i),
3449 multi_vec->GetVector(i-1));
3451 subSpaceProj->
Mult(y,
3452 multi_vec->GetVector(nev-1));
3460 if ( multi_vec == NULL )
3462 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::Solve()");
3464 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
3465 multi_vec->Randomize(seed);
3467 if ( subSpaceProj != NULL )
3470 y = multi_vec->GetVector(0);
3472 for (
int i=1; i<nev; i++)
3474 subSpaceProj->
Mult(multi_vec->GetVector(i),
3475 multi_vec->GetVector(i-1));
3477 subSpaceProj->
Mult(y, multi_vec->GetVector(nev-1));
3488 HYPRE_LOBPCGSolve(lobpcg_solver, NULL, *multi_vec, eigenvalues);
3492 HypreLOBPCG::OperatorMatvecCreate(
void *A,
3499 return ( matvec_data );
3503 HypreLOBPCG::OperatorMatvec(
void *matvec_data,
3504 HYPRE_Complex
alpha,
3510 MFEM_VERIFY(alpha == 1.0 && beta == 0.0,
"values not supported");
3512 Operator *Aop = (Operator*)A;
3514 int width = Aop->Width();
3516 hypre_ParVector * xPar = (hypre_ParVector *)x;
3517 hypre_ParVector * yPar = (hypre_ParVector *)y;
3519 Vector xVec(xPar->local_vector->data, width);
3520 Vector yVec(yPar->local_vector->data, width);
3522 Aop->Mult( xVec, yVec );
3528 HypreLOBPCG::OperatorMatvecDestroy(
void *matvec_data )
3534 HypreLOBPCG::PrecondSolve(
void *solver,
3539 Solver *
PC = (Solver*)solver;
3540 Operator *OP = (Operator*)A;
3542 int width = OP->Width();
3544 hypre_ParVector * bPar = (hypre_ParVector *)b;
3545 hypre_ParVector * xPar = (hypre_ParVector *)x;
3547 Vector bVec(bPar->local_vector->data, width);
3548 Vector xVec(xPar->local_vector->data, width);
3550 PC->Mult( bVec, xVec );
3556 HypreLOBPCG::PrecondSetup(
void *solver,
3574 MPI_Comm_size(comm,&numProcs);
3575 MPI_Comm_rank(comm,&myid);
3577 HYPRE_AMECreate(&ame_solver);
3578 HYPRE_AMESetPrintLevel(ame_solver, 0);
3585 mfem_hypre_TFree(multi_vec);
3590 for (
int i=0; i<nev; i++)
3592 delete eigenvectors[i];
3595 delete [] eigenvectors;
3599 mfem_hypre_TFree(eigenvalues);
3602 HYPRE_AMEDestroy(ame_solver);
3610 HYPRE_AMESetBlockSize(ame_solver, nev);
3616 HYPRE_AMESetTol(ame_solver, tol);
3622 #if MFEM_HYPRE_VERSION >= 21101
3623 HYPRE_AMESetRTol(ame_solver, rel_tol);
3625 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
3632 HYPRE_AMESetMaxIter(ame_solver, max_iter);
3640 HYPRE_AMESetPrintLevel(ame_solver, logging);
3647 ams_precond = &precond;
3655 HYPRE_Solver ams_precond_ptr = (HYPRE_Solver)*ams_precond;
3657 ams_precond->
SetupFcn()(*ams_precond,A,NULL,NULL);
3659 HYPRE_AMESetAMSSolver(ame_solver, ams_precond_ptr);
3662 HYPRE_AMESetup(ame_solver);
3668 HYPRE_ParCSRMatrix parcsr_M = M;
3669 HYPRE_AMESetMassMatrix(ame_solver,(HYPRE_ParCSRMatrix)parcsr_M);
3675 HYPRE_AMESolve(ame_solver);
3682 eigs.
SetSize(nev); eigs = -1.0;
3684 if ( eigenvalues == NULL )
3687 HYPRE_AMEGetEigenvalues(ame_solver,&eigenvalues);
3691 for (
int i=0; i<nev; i++)
3693 eigs[i] = eigenvalues[i];
3698 HypreAME::createDummyVectors()
3700 if ( multi_vec == NULL )
3702 HYPRE_AMEGetEigenvectors(ame_solver,&multi_vec);
3705 eigenvectors =
new HypreParVector*[nev];
3706 for (
int i=0; i<nev; i++)
3708 eigenvectors[i] =
new HypreParVector(multi_vec[i]);
3717 if ( eigenvectors == NULL )
3719 this->createDummyVectors();
3722 return *eigenvectors[i];
3728 if ( eigenvectors == NULL )
3730 this->createDummyVectors();
3735 eigenvectors = NULL;
virtual ~HypreBoomerAMG()
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
int Size() const
Logical size of the array.
void EliminateRowsCols(const Array< int > &rows_cols, const HypreParVector &X, HypreParVector &B)
virtual int NumNonZeroElems() const
Returns the number of the nonzero elements in the matrix.
double * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
Vector()
Default constructor for Vector. Sets size = 0 and data = NULL.
MPI_Comm GetComm() const
MPI communicator.
Vector * GlobalVector() const
Returns the global vector in each processor.
HypreParVector * X0
FIR Filter Temporary Vectors.
HypreParVector & GetEigenvector(unsigned int i)
Extract a single eigenvector.
double min_eig_est
Minimal eigenvalue estimate for polynomial smoothing.
void MakeDataOwner() const
Set the Vector data (host pointer) ownership flag.
void SetPrintLevel(int print_lvl)
void Print(const char *fname, HYPRE_Int offi=0, HYPRE_Int offj=0)
Prints the locally owned rows in parallel.
HYPRE_Int N() const
Returns the global number of columns.
HypreParMatrix * RAP(const HypreParMatrix *A, const HypreParMatrix *P)
Returns the matrix P^t * A * P.
int setup_called
Was hypre's Setup function called already?
void MakeRef(const HypreParMatrix &master)
Make this HypreParMatrix a reference to 'master'.
void Read_IJMatrix(MPI_Comm comm, const char *fname)
Read a matrix saved as a HYPRE_IJMatrix.
HypreParMatrix * LeftDiagMult(const SparseMatrix &D, HYPRE_Int *row_starts=NULL) const
Multiply the HypreParMatrix on the left by a block-diagonal parallel matrix D and return the result a...
HYPRE_Int MultTranspose(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A^t * x + beta * y.
void SetSize(int s)
Resize the vector to size s.
HypreParMatrix & Add(const double beta, const HypreParMatrix &B)
HypreParVector * B
Right-hand side and solution vector.
double window_params[3]
Parameters for windowing function of FIR filter.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void SetInitialVectors(int num_vecs, HypreParVector **vecs)
HypreADS(HypreParMatrix &A, ParFiniteElementSpace *face_fespace)
int * GetJ()
Return the array J.
void SetWindowByName(const char *window_name)
Convenience function for setting canonical windowing parameters.
int GetFaceOrder(int i) const
Returns the order of the i'th face finite element.
T * GetData()
Returns the data.
void GetEigenvalues(Array< double > &eigenvalues)
Collect the converged eigenvalues.
void SetPreconditioner(HypreSolver &precond)
int Size() const
Returns the size of the vector.
virtual N_Vector ToNVector()
Return a new wrapper SUNDIALS N_Vector of type SUNDIALS_NVEC_PARHYP.
int * GetI()
Return the array I.
void SetPreconditioner(Solver &precond)
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
void SetMassMatrix(Operator &M)
Abstract parallel finite element space.
double Normlinf() const
Returns the l_infinity norm of the vector.
void SetPrintLevel(int logging)
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
void SetOperator(HypreParMatrix &A)
void LoseData()
Lose the ownership of the graph (I, J) and data (A) arrays.
bool pos_l1_norms
If set, take absolute values of the computed l1_norms.
double * GetData() const
Return a pointer to the beginning of the Vector data.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A * x + beta * y.
void SetPrintLevel(int print_lvl)
void ScaleRows(const Vector &s)
Scale the local row i by s(i).
int Size_of_connections() const
double poly_fraction
Fraction of spectrum to smooth for polynomial relaxation.
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B)
Returns the matrix A * B.
void SetPrintLevel(int print_lvl)
int poly_scale
Apply the polynomial smoother to A or D^{-1/2} A D^{-1/2}.
void AddDomainInterpolator(DiscreteInterpolator *di)
Adds a domain interpolator. Assumes ownership of di.
double * GetData()
Return the element data, i.e. the array A.
void SetWindowParameters(double a, double b, double c)
Set parameters for windowing function for FIR smoother.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's GMRES.
void Print(const char *fname) const
Prints the locally owned rows in parallel.
void EliminateBC(HypreParMatrix &A, HypreParMatrix &Ae, const Array< int > &ess_dof_list, const Vector &X, Vector &B)
void SetSystemsOptions(int dim)
HypreLOBPCG(MPI_Comm comm)
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Relax the linear system Ax=b.
int GetNE() const
Returns number of elements in the mesh.
const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
HYPRE_Int GetGlobalNumRows() const
Return the global number of rows.
void SetSymmetry(int sym)
virtual ~HypreParaSails()
HYPRE_Int GetGlobalNumCols() const
Return the global number of columns.
void SetMaxIter(int max_iter)
double * l1_norms
l1 norms of the rows of A
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void SetLogging(int logging)
Mesh * GetMesh() const
Returns the mesh.
HyprePCG(HypreParMatrix &_A)
virtual HYPRE_PtrToParSolverFcn SolveFcn() const =0
hypre's internal Solve function
void SetRelTol(double rel_tol)
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
void SetResidualConvergenceOptions(int res_frequency=-1, double rtol=0.0)
int to_int(const std::string &str)
void GetBlocks(Array2D< HypreParMatrix * > &blocks, bool interleaved_rows=false, bool interleaved_cols=false) const
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve the linear system Ax=b.
HYPRE_Int GlobalTrueVSize() const
HypreParVector ** StealEigenvectors()
Transfer ownership of the converged eigenvectors.
HypreParMatrix * Transpose() const
Returns the transpose of *this.
HYPRE_Int Randomize(HYPRE_Int seed)
Set random values.
double relax_weight
Damping coefficient (usually <= 1)
void SetElasticityOptions(ParFiniteElementSpace *fespace)
void GetDiag(Vector &diag) const
Get the local diagonal of the matrix.
void Sort()
Sorts the array. This requires operator< to be defined for T.
int Size() const
Returns the number of TYPE I elements.
HypreParMatrix * A
The linear system matrix.
HypreAMS(HypreParMatrix &A, ParFiniteElementSpace *edge_fespace)
Dynamic 2D array using row-major layout.
virtual void SetOperator(const Operator &op)
virtual HYPRE_PtrToParSolverFcn SetupFcn() const =0
hypre's internal Setup function
void SetLogging(int logging)
HypreParMatrix()
An empty matrix to be used as a reference to an existing matrix.
void SetMaxIter(int max_iter)
int ParCSRRelax_FIR(hypre_ParCSRMatrix *A, hypre_ParVector *f, double max_eig, int poly_order, double *fir_coeffs, hypre_ParVector *u, hypre_ParVector *x0, hypre_ParVector *x1, hypre_ParVector *x2, hypre_ParVector *x3)
HypreParMatrix * ParallelAssemble() const
Returns the matrix "assembled" on the true dofs.
void SetSOROptions(double relax_weight, double omega)
Set SOR-related parameters.
int SpaceDimension() const
Wrapper for hypre's parallel vector class.
double Norml1() const
Returns the l_1 norm of the vector.
int ParCSRRelax_Taubin(hypre_ParCSRMatrix *A, hypre_ParVector *f, double lambda, double mu, int N, double max_eig, hypre_ParVector *u, hypre_ParVector *r)
void GetEigenvalues(Array< double > &eigenvalues)
Collect the converged eigenvalues.
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
void SetPrintLevel(int print_lvl)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
void Solve()
Solve the eigenproblem.
void AddTraceFaceInterpolator(DiscreteInterpolator *di)
Adds a trace face interpolator. Assumes ownership of di.
int GetOrder(int i) const
Returns the order of the i'th finite element.
void SetNumModes(int num_eigs)
int GetNumRows() const
Returns the number of rows in the diagonal block of the ParCSRMatrix.
HypreParMatrix * ParAdd(const HypreParMatrix *A, const HypreParMatrix *B)
Returns the matrix A + B.
double max_eig_est
Maximal eigenvalue estimate for polynomial smoothing.
A class to initialize the size of a Tensor.
void SetRelTol(double rel_tol)
int height
Dimension of the output / number of rows in the matrix.
void SetMaxIter(int max_iter)
void SetFIRCoefficients(double max_eig)
Compute window and Chebyshev coefficients for given polynomial order.
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
double * fir_coeffs
Combined coefficients for windowing and Chebyshev polynomials.
void Threshold(double threshold=0.0)
Remove values smaller in absolute value than some threshold.
double InnerProduct(HypreParVector *x, HypreParVector *y)
HypreParVector(MPI_Comm comm, HYPRE_Int glob_size, HYPRE_Int *col)
Creates vector with given global size and parallel partitioning of the rows/columns given by col...
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void SetData(double *_data)
Sets the data of the Vector and the hypre_ParVector to _data.
void InvScaleRows(const Vector &s)
Scale the local row i by 1./s(i)
void SetTaubinOptions(double lambda, double mu, int iter)
Set parameters for Taubin's lambda-mu method.
HypreParVector * B
Right-hand side and solution vectors.
void SetMassMatrix(HypreParMatrix &M)
HYPRE_Int M() const
Returns the global number of rows.
int GetNumCols() const
Returns the number of columns in the diagonal block of the ParCSRMatrix.
void SetOperator(Operator &A)
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
void SetPolyOptions(int poly_order, double poly_fraction)
Set parameters for polynomial smoothing.
int relax_times
Number of relaxation sweeps.
void operator*=(double s)
Scale all entries by s: A_scaled = s*A.
void SetPrintLevel(int logging)
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
double ParNormlp(const Vector &vec, double p, MPI_Comm comm)
Compute the l_p norm of the Vector which is split without overlap across the given communicator...
void SetOwnership(int own)
Sets ownership of the internal hypre_ParVector.
void SetDataOwner(bool owna)
Set the data ownership flag (A array).
Abstract class for hypre's solvers and preconditioners.
double * HostWrite()
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
HypreParVector & operator=(double d)
Set constant values.
HYPRE_Int * GetTrueDofOffsets() const
HypreEuclid(HypreParMatrix &A)
Arbitrary order H(curl)-conforming Nedelec finite elements.
const FiniteElementCollection * FEColl() const
void PrintCommPkg(std::ostream &out=mfem::out) const
Print information about the hypre_ParCSRCommPkg of the HypreParMatrix.
HypreGMRES(HypreParMatrix &_A)
void GetParBlocks(Array2D< HypreParMatrix * > &blocks) const
hypre_ParCSRMatrix * StealData()
Changes the ownership of the the matrix.
void SetPrecondUsageMode(int pcg_mode)
HypreParMatrix * A
The linear system matrix.
Arbitrary order H1-conforming (continuous) finite elements.
void SetMaxIter(int max_iter)
void GetOffd(SparseMatrix &offd, HYPRE_Int *&cmap) const
Get the local off-diagonal block. NOTE: 'offd' will not own any data.
HYPRE_Int * GetColStarts() const
Return the parallel column partitioning array.
HypreParVector & GetEigenvector(unsigned int i)
Extract a single eigenvector.
double omega
SOR parameter (usually in (0,2))
HYPRE_Int * GetRowStarts() const
Return the parallel row partitioning array.
Class for parallel grid function.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Wrapper for hypre's ParCSR matrix class.
void Swap(SparseMatrix &other)
~HypreParVector()
Calls hypre's destroy function.
virtual void Assemble(int skip_zeros=1)
Construct the internal matrix representation of the discrete linear operator.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's PCG.
Class for parallel meshes.
void Solve()
Solve the eigenproblem.
void Read(MPI_Comm comm, const char *fname)
Reads the matrix from a file.
HypreParVector * V
Temporary vectors.
void SetType(HypreSmoother::Type type, int relax_times=1)
Set the relaxation type and number of sweeps.
HypreParaSails(HypreParMatrix &A)
int width
Dimension of the input / number of columns in the matrix.
int poly_order
Order of the smoothing polynomial.
double lambda
Taubin's lambda-mu method parameters.
void ParallelProject(Vector &tv) const
Returns the vector restricted to the true dofs.
double sigma(const Vector &x)