12 #include "../config/config.hpp"
17 #include "../fem/fem.hpp"
24 #ifdef MFEM_USE_SUNDIALS
25 #include <nvector/nvector_parallel.h>
33 template<
typename TargetT,
typename SourceT>
34 static TargetT *DuplicateAs(
const SourceT *array,
int size,
35 bool cplusplus =
true)
37 TargetT *target_array = cplusplus ? (TargetT*) Memory<TargetT>(size)
38 : mfem_hypre_TAlloc(TargetT, size);
39 for (
int i = 0; i < size; i++)
41 target_array[i] = array[i];
46 inline void HypreParVector::_SetDataAndSize_()
48 SetDataAndSize(hypre_VectorData(hypre_ParVectorLocalVector(x)),
50 hypre_VectorSize(hypre_ParVectorLocalVector(x))));
53 HypreParVector::HypreParVector(MPI_Comm comm, HYPRE_Int glob_size,
56 x = hypre_ParVectorCreate(comm,glob_size,col);
57 hypre_ParVectorInitialize(x);
58 hypre_ParVectorSetPartitioningOwner(x,0);
60 hypre_ParVectorSetDataOwner(x,1);
61 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
67 double *_data, HYPRE_Int *col) :
Vector()
69 x = hypre_ParVectorCreate(comm,glob_size,col);
70 hypre_ParVectorSetDataOwner(x,1);
71 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),0);
72 hypre_ParVectorSetPartitioningOwner(x,0);
74 hypre_VectorData(hypre_ParVectorLocalVector(x)) = &tmp;
77 hypre_ParVectorInitialize(x);
79 hypre_VectorData(hypre_ParVectorLocalVector(x)) = _data;
86 x = hypre_ParVectorCreate(y.x -> comm, y.x -> global_size,
88 hypre_ParVectorInitialize(x);
89 hypre_ParVectorSetPartitioningOwner(x,0);
90 hypre_ParVectorSetDataOwner(x,1);
91 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
101 x = hypre_ParVectorInDomainOf(const_cast<HypreParMatrix&>(A));
105 x = hypre_ParVectorInRangeOf(const_cast<HypreParMatrix&>(A));
113 x = (hypre_ParVector *) y;
122 hypre_ParVectorInitialize(x);
123 hypre_ParVectorSetPartitioningOwner(x,0);
125 hypre_ParVectorSetDataOwner(x,1);
126 hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
133 hypre_Vector *hv = hypre_ParVectorToVectorAll(*
this);
136 hypre_SeqVectorSetDataOwner(hv,0);
137 hypre_SeqVectorDestroy(hv);
150 if (size != y.
Size())
162 hypre_VectorData(hypre_ParVectorLocalVector(x)) = _data;
168 return hypre_ParVectorSetRandomValues(x,seed);
173 hypre_ParVectorPrint(x,fname);
180 hypre_ParVectorDestroy(x);
184 #ifdef MFEM_USE_SUNDIALS
191 #endif // MFEM_USE_SUNDIALS
196 return hypre_ParVectorInnerProd(*x, *y);
201 return hypre_ParVectorInnerProd(x, y);
210 double loc_norm = vec.
Norml1();
211 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
215 double loc_norm = vec*vec;
216 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
222 for (
int i = 0; i < vec.
Size(); i++)
224 sum += pow(fabs(vec(i)), p);
226 MPI_Allreduce(&sum, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
227 norm = pow(norm, 1.0/p);
232 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_MAX, comm);
238 void HypreParMatrix::Init()
242 diagOwner = offdOwner = colMapOwner = -1;
252 char HypreParMatrix::CopyCSR(
SparseMatrix *csr, hypre_CSRMatrix *hypre_csr)
254 hypre_CSRMatrixData(hypre_csr) = csr->
GetData();
256 hypre_CSRMatrixI(hypre_csr) = csr->
GetI();
257 hypre_CSRMatrixJ(hypre_csr) = csr->
GetJ();
261 hypre_CSRMatrixI(hypre_csr) =
262 DuplicateAs<HYPRE_Int>(csr->
GetI(), csr->
Height()+1);
263 hypre_CSRMatrixJ(hypre_csr) =
270 char HypreParMatrix::CopyBoolCSR(Table *bool_csr, hypre_CSRMatrix *hypre_csr)
272 int nnz = bool_csr->Size_of_connections();
273 double *data =
new double[nnz];
274 for (
int i = 0; i < nnz; i++)
278 hypre_CSRMatrixData(hypre_csr) = data;
280 hypre_CSRMatrixI(hypre_csr) = bool_csr->GetI();
281 hypre_CSRMatrixJ(hypre_csr) = bool_csr->GetJ();
285 hypre_CSRMatrixI(hypre_csr) =
286 DuplicateAs<HYPRE_Int>(bool_csr->GetI(), bool_csr->Size()+1);
287 hypre_CSRMatrixJ(hypre_csr) =
288 DuplicateAs<HYPRE_Int>(bool_csr->GetJ(), nnz);
294 void HypreParMatrix::CopyCSR_J(hypre_CSRMatrix *hypre_csr,
int *J)
296 HYPRE_Int nnz = hypre_CSRMatrixNumNonzeros(hypre_csr);
297 for (HYPRE_Int j = 0; j < nnz; j++)
299 J[j] = int(hypre_CSRMatrixJ(hypre_csr)[j]);
306 :
Operator(diag->Height(), diag->Width())
309 A = hypre_ParCSRMatrixCreate(comm, glob_size, glob_size, row_starts,
311 hypre_ParCSRMatrixSetDataOwner(A,1);
312 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
313 hypre_ParCSRMatrixSetColStartsOwner(A,0);
315 hypre_CSRMatrixSetDataOwner(A->diag,0);
316 diagOwner = CopyCSR(diag, A->diag);
317 hypre_CSRMatrixSetRownnz(A->diag);
319 hypre_CSRMatrixSetDataOwner(A->offd,1);
320 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
327 hypre_ParCSRMatrixSetNumNonzeros(A);
330 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
332 CopyCSR_J(A->diag, diag->
GetJ());
335 hypre_MatvecCommPkgCreate(A);
340 HYPRE_Int global_num_rows,
341 HYPRE_Int global_num_cols,
342 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
344 :
Operator(diag->Height(), diag->Width())
347 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
348 row_starts, col_starts,
350 hypre_ParCSRMatrixSetDataOwner(A,1);
351 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
352 hypre_ParCSRMatrixSetColStartsOwner(A,0);
354 hypre_CSRMatrixSetDataOwner(A->diag,0);
355 diagOwner = CopyCSR(diag, A->diag);
356 hypre_CSRMatrixSetRownnz(A->diag);
358 hypre_CSRMatrixSetDataOwner(A->offd,1);
359 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
361 hypre_ParCSRMatrixSetNumNonzeros(A);
364 if (row_starts == col_starts)
366 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
368 CopyCSR_J(A->diag, diag->
GetJ());
372 hypre_MatvecCommPkgCreate(A);
377 HYPRE_Int global_num_rows,
378 HYPRE_Int global_num_cols,
379 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
382 :
Operator(diag->Height(), diag->Width())
385 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
386 row_starts, col_starts,
389 hypre_ParCSRMatrixSetDataOwner(A,1);
390 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
391 hypre_ParCSRMatrixSetColStartsOwner(A,0);
393 hypre_CSRMatrixSetDataOwner(A->diag,0);
394 diagOwner = CopyCSR(diag, A->diag);
395 hypre_CSRMatrixSetRownnz(A->diag);
397 hypre_CSRMatrixSetDataOwner(A->offd,0);
398 offdOwner = CopyCSR(offd, A->offd);
399 hypre_CSRMatrixSetRownnz(A->offd);
401 hypre_ParCSRMatrixColMapOffd(A) = cmap;
405 hypre_ParCSRMatrixSetNumNonzeros(A);
408 if (row_starts == col_starts)
410 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
412 CopyCSR_J(A->diag, diag->
GetJ());
416 hypre_MatvecCommPkgCreate(A);
422 HYPRE_Int global_num_rows, HYPRE_Int global_num_cols,
423 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
424 HYPRE_Int *diag_i, HYPRE_Int *diag_j,
double *diag_data,
425 HYPRE_Int *offd_i, HYPRE_Int *offd_j,
double *offd_data,
426 HYPRE_Int offd_num_cols, HYPRE_Int *offd_col_map)
429 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
430 row_starts, col_starts, offd_num_cols, 0, 0);
431 hypre_ParCSRMatrixSetDataOwner(A,1);
432 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
433 hypre_ParCSRMatrixSetColStartsOwner(A,0);
435 HYPRE_Int local_num_rows = hypre_CSRMatrixNumRows(A->diag);
437 hypre_CSRMatrixSetDataOwner(A->diag,0);
438 hypre_CSRMatrixI(A->diag) = diag_i;
439 hypre_CSRMatrixJ(A->diag) = diag_j;
440 hypre_CSRMatrixData(A->diag) = diag_data;
441 hypre_CSRMatrixNumNonzeros(A->diag) = diag_i[local_num_rows];
442 hypre_CSRMatrixSetRownnz(A->diag);
446 hypre_CSRMatrixSetDataOwner(A->offd,0);
447 hypre_CSRMatrixI(A->offd) = offd_i;
448 hypre_CSRMatrixJ(A->offd) = offd_j;
449 hypre_CSRMatrixData(A->offd) = offd_data;
450 hypre_CSRMatrixNumNonzeros(A->offd) = offd_i[local_num_rows];
451 hypre_CSRMatrixSetRownnz(A->offd);
455 hypre_ParCSRMatrixColMapOffd(A) = offd_col_map;
459 hypre_ParCSRMatrixSetNumNonzeros(A);
462 if (row_starts == col_starts)
464 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
467 hypre_MatvecCommPkgCreate(A);
475 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
478 MFEM_ASSERT(sm_a != NULL,
"invalid input");
479 MFEM_VERIFY(!HYPRE_AssumedPartitionCheck(),
480 "this method can not be used with assumed partition");
484 hypre_CSRMatrix *csr_a;
485 csr_a = hypre_CSRMatrixCreate(sm_a ->
Height(), sm_a ->
Width(),
486 sm_a -> NumNonZeroElems());
488 hypre_CSRMatrixSetDataOwner(csr_a,0);
489 CopyCSR(sm_a, csr_a);
490 hypre_CSRMatrixSetRownnz(csr_a);
492 A = hypre_CSRMatrixToParCSRMatrix(comm, csr_a, row_starts, col_starts);
495 delete [] hypre_CSRMatrixI(csr_a);
496 delete [] hypre_CSRMatrixJ(csr_a);
498 hypre_CSRMatrixI(csr_a) = NULL;
499 hypre_CSRMatrixDestroy(csr_a);
505 if (row_starts == col_starts)
507 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
510 hypre_MatvecCommPkgCreate(A);
515 HYPRE_Int global_num_rows,
516 HYPRE_Int global_num_cols,
517 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
522 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
523 row_starts, col_starts, 0, nnz, 0);
524 hypre_ParCSRMatrixSetDataOwner(A,1);
525 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
526 hypre_ParCSRMatrixSetColStartsOwner(A,0);
528 hypre_CSRMatrixSetDataOwner(A->diag,0);
529 diagOwner = CopyBoolCSR(diag, A->diag);
530 hypre_CSRMatrixSetRownnz(A->diag);
532 hypre_CSRMatrixSetDataOwner(A->offd,1);
533 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Size()+1);
535 hypre_ParCSRMatrixSetNumNonzeros(A);
538 if (row_starts == col_starts)
540 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
542 CopyCSR_J(A->diag, diag->
GetJ());
546 hypre_MatvecCommPkgCreate(A);
555 HYPRE_Int *row, HYPRE_Int *col,
556 HYPRE_Int *i_diag, HYPRE_Int *j_diag,
557 HYPRE_Int *i_offd, HYPRE_Int *j_offd,
558 HYPRE_Int *cmap, HYPRE_Int cmap_size)
560 HYPRE_Int diag_nnz, offd_nnz;
563 if (HYPRE_AssumedPartitionCheck())
565 diag_nnz = i_diag[row[1]-row[0]];
566 offd_nnz = i_offd[row[1]-row[0]];
568 A = hypre_ParCSRMatrixCreate(comm, row[2], col[2], row, col,
569 cmap_size, diag_nnz, offd_nnz);
573 diag_nnz = i_diag[row[
id+1]-row[id]];
574 offd_nnz = i_offd[row[
id+1]-row[id]];
576 A = hypre_ParCSRMatrixCreate(comm, row[np], col[np], row, col,
577 cmap_size, diag_nnz, offd_nnz);
580 hypre_ParCSRMatrixSetDataOwner(A,1);
581 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
582 hypre_ParCSRMatrixSetColStartsOwner(A,0);
587 for (i = 0; i < diag_nnz; i++)
593 for (i = 0; i < offd_nnz; i++)
598 hypre_CSRMatrixSetDataOwner(A->diag,0);
599 hypre_CSRMatrixI(A->diag) = i_diag;
600 hypre_CSRMatrixJ(A->diag) = j_diag;
601 hypre_CSRMatrixData(A->diag) = a_diag;
602 hypre_CSRMatrixSetRownnz(A->diag);
606 hypre_CSRMatrixSetDataOwner(A->offd,0);
607 hypre_CSRMatrixI(A->offd) = i_offd;
608 hypre_CSRMatrixJ(A->offd) = j_offd;
609 hypre_CSRMatrixData(A->offd) = a_offd;
610 hypre_CSRMatrixSetRownnz(A->offd);
614 hypre_ParCSRMatrixColMapOffd(A) = cmap;
618 hypre_ParCSRMatrixSetNumNonzeros(A);
623 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
626 hypre_MatvecCommPkgCreate(A);
636 HYPRE_Int glob_ncols,
int *I, HYPRE_Int *J,
637 double *data, HYPRE_Int *rows, HYPRE_Int *cols)
643 HYPRE_Int my_col_start, my_col_end;
644 if (HYPRE_AssumedPartitionCheck())
647 my_col_start = cols[0];
648 my_col_end = cols[1];
653 MPI_Comm_rank(comm, &myid);
654 MPI_Comm_size(comm, &part_size);
656 my_col_start = cols[myid];
657 my_col_end = cols[myid+1];
661 HYPRE_Int *row_starts, *col_starts;
664 row_starts = col_starts = mfem_hypre_TAlloc(HYPRE_Int, part_size);
665 for (
int i = 0; i < part_size; i++)
667 row_starts[i] = rows[i];
672 row_starts = mfem_hypre_TAlloc(HYPRE_Int, part_size);
673 col_starts = mfem_hypre_TAlloc(HYPRE_Int, part_size);
674 for (
int i = 0; i < part_size; i++)
676 row_starts[i] = rows[i];
677 col_starts[i] = cols[i];
683 HYPRE_Int diag_nnz = 0, offd_nnz = 0, offd_num_cols = 0;
684 map<HYPRE_Int, HYPRE_Int> offd_map;
685 for (HYPRE_Int j = 0, loc_nnz = I[nrows]; j < loc_nnz; j++)
687 HYPRE_Int glob_col = J[j];
688 if (my_col_start <= glob_col && glob_col < my_col_end)
694 offd_map.insert(pair<const HYPRE_Int, HYPRE_Int>(glob_col, -1));
699 for (map<HYPRE_Int, HYPRE_Int>::iterator it = offd_map.begin();
700 it != offd_map.end(); ++it)
702 it->second = offd_num_cols++;
706 A = hypre_ParCSRMatrixCreate(comm, glob_nrows, glob_ncols,
707 row_starts, col_starts, offd_num_cols,
709 hypre_ParCSRMatrixInitialize(A);
711 HYPRE_Int *diag_i, *diag_j, *offd_i, *offd_j, *offd_col_map;
712 double *diag_data, *offd_data;
715 diag_data = A->diag->data;
718 offd_data = A->offd->data;
719 offd_col_map = A->col_map_offd;
721 diag_nnz = offd_nnz = 0;
722 for (HYPRE_Int i = 0, j = 0; i < nrows; i++)
724 diag_i[i] = diag_nnz;
725 offd_i[i] = offd_nnz;
726 for (HYPRE_Int j_end = I[i+1]; j < j_end; j++)
728 HYPRE_Int glob_col = J[j];
729 if (my_col_start <= glob_col && glob_col < my_col_end)
731 diag_j[diag_nnz] = glob_col - my_col_start;
732 diag_data[diag_nnz] = data[j];
737 offd_j[offd_nnz] = offd_map[glob_col];
738 offd_data[offd_nnz] = data[j];
743 diag_i[nrows] = diag_nnz;
744 offd_i[nrows] = offd_nnz;
745 for (map<HYPRE_Int, HYPRE_Int>::iterator it = offd_map.begin();
746 it != offd_map.end(); ++it)
748 offd_col_map[it->second] = it->first;
751 hypre_ParCSRMatrixSetNumNonzeros(A);
753 if (row_starts == col_starts)
755 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
757 hypre_MatvecCommPkgCreate(A);
765 hypre_ParCSRMatrix *Ph =
static_cast<hypre_ParCSRMatrix *
>(P);
770 A = hypre_ParCSRMatrixCompleteClone(Ph);
772 hypre_ParCSRMatrixCopy(Ph, A, 1);
780 hypre_ParCSRMatrixSetNumNonzeros(A);
782 hypre_MatvecCommPkgCreate(A);
800 MFEM_ASSERT(diagOwner == -1 && offdOwner == -1 && colMapOwner == -1,
"");
801 MFEM_ASSERT(ParCSROwner,
"");
802 hypre_ParCSRMatrix *R = A;
811 if (!A || hypre_ParCSRMatrixOwnsRowStarts(A) ||
812 (hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
813 hypre_ParCSRMatrixOwnsColStarts(A)))
819 if (HYPRE_AssumedPartitionCheck())
825 MPI_Comm_size(hypre_ParCSRMatrixComm(A), &row_starts_size);
829 HYPRE_Int *old_row_starts = hypre_ParCSRMatrixRowStarts(A);
830 HYPRE_Int *new_row_starts = mfem_hypre_CTAlloc(HYPRE_Int, row_starts_size);
831 for (
int i = 0; i < row_starts_size; i++)
833 new_row_starts[i] = old_row_starts[i];
836 hypre_ParCSRMatrixRowStarts(A) = new_row_starts;
837 hypre_ParCSRMatrixOwnsRowStarts(A) = 1;
839 if (hypre_ParCSRMatrixColStarts(A) == old_row_starts)
841 hypre_ParCSRMatrixColStarts(A) = new_row_starts;
842 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
848 if (!A || hypre_ParCSRMatrixOwnsColStarts(A) ||
849 (hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
850 hypre_ParCSRMatrixOwnsRowStarts(A)))
856 if (HYPRE_AssumedPartitionCheck())
862 MPI_Comm_size(hypre_ParCSRMatrixComm(A), &col_starts_size);
866 HYPRE_Int *old_col_starts = hypre_ParCSRMatrixColStarts(A);
867 HYPRE_Int *new_col_starts = mfem_hypre_CTAlloc(HYPRE_Int, col_starts_size);
868 for (
int i = 0; i < col_starts_size; i++)
870 new_col_starts[i] = old_col_starts[i];
873 hypre_ParCSRMatrixColStarts(A) = new_col_starts;
875 if (hypre_ParCSRMatrixRowStarts(A) == old_col_starts)
877 hypre_ParCSRMatrixRowStarts(A) = new_col_starts;
878 hypre_ParCSRMatrixOwnsRowStarts(A) = 1;
879 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
883 hypre_ParCSRMatrixOwnsColStarts(A) = 1;
891 for (
int j = 0; j < size; j++)
893 diag(j) = A->diag->data[A->diag->i[j]];
894 MFEM_ASSERT(A->diag->j[A->diag->i[j]] == j,
895 "the first entry in each row must be the diagonal one");
899 static void MakeWrapper(
const hypre_CSRMatrix *mat,
SparseMatrix &wrapper)
901 HYPRE_Int nr = hypre_CSRMatrixNumRows(mat);
902 HYPRE_Int nc = hypre_CSRMatrixNumCols(mat);
905 hypre_CSRMatrixJ(mat),
906 hypre_CSRMatrixData(mat),
907 nr, nc,
false,
false,
false);
909 HYPRE_Int nnz = hypre_CSRMatrixNumNonzeros(mat);
910 SparseMatrix tmp(DuplicateAs<int>(hypre_CSRMatrixI(mat), nr+1),
911 DuplicateAs<int>(hypre_CSRMatrixJ(mat), nnz),
912 hypre_CSRMatrixData(mat),
913 nr, nc,
true,
false,
false);
920 MakeWrapper(A->diag, diag);
925 MakeWrapper(A->offd, offd);
926 cmap = A->col_map_offd;
930 bool interleaved_rows,
931 bool interleaved_cols)
const
936 hypre_ParCSRMatrix **hypre_blocks =
new hypre_ParCSRMatrix*[nr * nc];
937 internal::hypre_ParCSRMatrixSplit(A, nr, nc, hypre_blocks,
938 interleaved_rows, interleaved_cols);
940 for (
int i = 0; i < nr; i++)
942 for (
int j = 0; j < nc; j++)
948 delete [] hypre_blocks;
953 hypre_ParCSRMatrix * At;
954 hypre_ParCSRMatrixTranspose(A, &At, 1);
955 hypre_ParCSRMatrixSetNumNonzeros(At);
957 hypre_MatvecCommPkgCreate(At);
963 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(At));
974 return hypre_ParCSRMatrixMatvec(a, A, x, b, y);
979 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
980 <<
", expected size = " <<
Width());
981 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
982 <<
", expected size = " <<
Height());
990 const_cast<double*>(x_data),
999 X->
SetData(const_cast<double*>(x_data));
1003 hypre_ParCSRMatrixMatvec(a, A, *X, b, *Y);
1009 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
1010 <<
", expected size = " <<
Height());
1011 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
1012 <<
", expected size = " <<
Width());
1026 const_cast<double*>(x_data),
1032 Y->
SetData(const_cast<double*>(x_data));
1035 hypre_ParCSRMatrixMatvecT(a, A, *Y, b, *X);
1041 return hypre_ParCSRMatrixMatvec(a, A, (hypre_ParVector *) x, b,
1042 (hypre_ParVector *) y);
1048 return hypre_ParCSRMatrixMatvecT(a, A, x, b, y);
1054 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1055 <<
", expected size = " <<
Width());
1056 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1057 <<
", expected size = " <<
Height());
1062 internal::hypre_ParCSRMatrixAbsMatvec(A, a, const_cast<double*>(x_data),
1069 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
1070 <<
", expected size = " <<
Height());
1071 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
1072 <<
", expected size = " <<
Width());
1077 internal::hypre_ParCSRMatrixAbsMatvecT(A, a, const_cast<double*>(x_data),
1082 HYPRE_Int* row_starts)
const
1084 const bool assumed_partition = HYPRE_AssumedPartitionCheck();
1085 const bool row_starts_given = (row_starts != NULL);
1086 if (!row_starts_given)
1088 row_starts = hypre_ParCSRMatrixRowStarts(A);
1089 MFEM_VERIFY(D.
Height() == hypre_CSRMatrixNumRows(A->diag),
1090 "the matrix D is NOT compatible with the row starts of"
1091 " this HypreParMatrix, row_starts must be given.");
1096 if (assumed_partition)
1102 MPI_Comm_rank(
GetComm(), &offset);
1104 int local_num_rows = row_starts[offset+1]-row_starts[offset];
1105 MFEM_VERIFY(local_num_rows == D.
Height(),
"the number of rows in D is "
1106 " not compatible with the given row_starts");
1112 HYPRE_Int global_num_rows;
1113 if (assumed_partition)
1116 if (row_starts_given)
1118 global_num_rows = row_starts[2];
1125 global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
1130 MPI_Comm_size(
GetComm(), &part_size);
1131 global_num_rows = row_starts[part_size];
1135 HYPRE_Int *col_starts = hypre_ParCSRMatrixColStarts(A);
1136 HYPRE_Int *col_map_offd;
1141 GetOffd(A_offd, col_map_offd);
1149 global_num_rows, hypre_ParCSRMatrixGlobalNumCols(A),
1150 DuplicateAs<HYPRE_Int>(row_starts, part_size,
false),
1151 DuplicateAs<HYPRE_Int>(col_starts, part_size,
false),
1153 DuplicateAs<HYPRE_Int>(col_map_offd, A_offd.
Width()));
1158 #ifndef HYPRE_BIGINT
1169 hypre_ParCSRMatrixSetRowStartsOwner(DA->A, 1);
1170 hypre_ParCSRMatrixSetColStartsOwner(DA->A, 1);
1172 DA->diagOwner = DA->offdOwner = 3;
1173 DA->colMapOwner = 1;
1180 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
1185 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
1187 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
1191 double *Adiag_data = hypre_CSRMatrixData(A->diag);
1192 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
1195 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
1196 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
1199 for (
int i(0); i < size; ++i)
1202 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
1204 Adiag_data[jj] *= val;
1206 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
1208 Aoffd_data[jj] *= val;
1215 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
1220 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
1222 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
1226 double *Adiag_data = hypre_CSRMatrixData(A->diag);
1227 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
1230 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
1231 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
1234 for (
int i(0); i < size; ++i)
1239 mfem_error(
"HypreParMatrix::InvDiagScale : Division by 0");
1243 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
1245 Adiag_data[jj] *= val;
1247 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
1249 Aoffd_data[jj] *= val;
1256 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
1261 HYPRE_Int size=hypre_CSRMatrixNumRows(A->diag);
1264 double *Adiag_data = hypre_CSRMatrixData(A->diag);
1265 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
1266 for (jj = 0; jj < Adiag_i[size]; ++jj)
1268 Adiag_data[jj] *= s;
1271 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
1272 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
1273 for (jj = 0; jj < Aoffd_i[size]; ++jj)
1275 Aoffd_data[jj] *= s;
1279 static void get_sorted_rows_cols(
const Array<int> &rows_cols,
1284 for (
int i = 0; i < rows_cols.
Size(); i++)
1286 hypre_sorted[i] = rows_cols[i];
1287 if (i && rows_cols[i-1] > rows_cols[i]) { sorted =
false; }
1289 if (!sorted) { hypre_sorted.
Sort(); }
1297 hypre_CSRMatrix * csr_A;
1298 hypre_CSRMatrix * csr_A_wo_z;
1299 hypre_ParCSRMatrix * parcsr_A_ptr;
1300 HYPRE_Int * row_starts = NULL; HYPRE_Int * col_starts = NULL;
1301 HYPRE_Int row_start = -1; HYPRE_Int row_end = -1;
1302 HYPRE_Int col_start = -1; HYPRE_Int col_end = -1;
1304 comm = hypre_ParCSRMatrixComm(A);
1306 ierr += hypre_ParCSRMatrixGetLocalRange(A,
1307 &row_start,&row_end,
1308 &col_start,&col_end );
1310 row_starts = hypre_ParCSRMatrixRowStarts(A);
1311 col_starts = hypre_ParCSRMatrixColStarts(A);
1313 bool old_owns_row = hypre_ParCSRMatrixOwnsRowStarts(A);
1314 bool old_owns_col = hypre_ParCSRMatrixOwnsColStarts(A);
1315 HYPRE_Int global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
1316 HYPRE_Int global_num_cols = hypre_ParCSRMatrixGlobalNumCols(A);
1317 parcsr_A_ptr = hypre_ParCSRMatrixCreate(comm, global_num_rows,
1319 row_starts, col_starts,
1321 hypre_ParCSRMatrixOwnsRowStarts(parcsr_A_ptr) = old_owns_row;
1322 hypre_ParCSRMatrixOwnsColStarts(parcsr_A_ptr) = old_owns_col;
1323 hypre_ParCSRMatrixOwnsRowStarts(A) = 0;
1324 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
1326 csr_A = hypre_MergeDiagAndOffd(A);
1332 csr_A_wo_z = hypre_CSRMatrixDeleteZeros(csr_A,threshold);
1336 if (csr_A_wo_z == NULL)
1342 ierr += hypre_CSRMatrixDestroy(csr_A);
1348 ierr += GenerateDiagAndOffd(csr_A_wo_z,parcsr_A_ptr,
1351 ierr += hypre_CSRMatrixDestroy(csr_A_wo_z);
1353 MFEM_VERIFY(ierr == 0,
"");
1357 hypre_ParCSRMatrixSetNumNonzeros(A);
1359 if (row_starts == col_starts)
1361 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1363 hypre_MatvecCommPkgCreate(A);
1373 get_sorted_rows_cols(rows_cols, rc_sorted);
1375 internal::hypre_ParCSRMatrixEliminateAXB(
1382 get_sorted_rows_cols(rows_cols, rc_sorted);
1384 hypre_ParCSRMatrix* Ae;
1385 internal::hypre_ParCSRMatrixEliminateAAe(
1394 get_sorted_rows_cols(cols, rc_sorted);
1396 hypre_ParCSRMatrix* Ae;
1397 internal::hypre_ParCSRMatrixEliminateAAe(
1398 A, &Ae, rc_sorted.
Size(), rc_sorted.
GetData(), 1);
1405 if (rows.
Size() > 0)
1408 get_sorted_rows_cols(rows, r_sorted);
1409 internal::hypre_ParCSRMatrixEliminateRows(A, r_sorted.
Size(),
1416 hypre_ParCSRMatrixPrintIJ(A,offi,offj,fname);
1424 HYPRE_Int base_i, base_j;
1425 hypre_ParCSRMatrixReadIJ(comm, fname, &base_i, &base_j, &A);
1426 hypre_ParCSRMatrixSetNumNonzeros(A);
1428 hypre_MatvecCommPkgCreate(A);
1439 HYPRE_IJMatrix A_ij;
1440 HYPRE_IJMatrixRead(fname, comm, 5555, &A_ij);
1442 HYPRE_ParCSRMatrix A_parcsr;
1443 HYPRE_IJMatrixGetObject(A_ij, (
void**) &A_parcsr);
1445 A = (hypre_ParCSRMatrix*)A_parcsr;
1447 hypre_ParCSRMatrixSetNumNonzeros(A);
1449 hypre_MatvecCommPkgCreate(A);
1457 hypre_ParCSRCommPkg *comm_pkg = A->comm_pkg;
1458 MPI_Comm comm = A->comm;
1460 const int tag = 46801;
1462 MPI_Comm_rank(comm, &myid);
1463 MPI_Comm_size(comm, &nproc);
1467 MPI_Recv(&c, 1, MPI_CHAR, myid-1, tag, comm, MPI_STATUS_IGNORE);
1471 out <<
"\nHypreParMatrix: hypre_ParCSRCommPkg:\n";
1473 out <<
"Rank " << myid <<
":\n"
1474 " number of sends = " << comm_pkg->num_sends <<
1475 " (" <<
sizeof(double)*comm_pkg->send_map_starts[comm_pkg->num_sends] <<
1477 " number of recvs = " << comm_pkg->num_recvs <<
1478 " (" <<
sizeof(
double)*comm_pkg->recv_vec_starts[comm_pkg->num_recvs] <<
1480 if (myid != nproc-1)
1483 MPI_Send(&c, 1, MPI_CHAR, myid+1, tag, comm);
1494 HYPRE_Complex *data = hypre_CSRMatrixData(M);
1500 HYPRE_Int *A_col_map_offd = hypre_ParCSRMatrixColMapOffd(A);
1501 int size = hypre_CSRMatrixNumCols(hypre_ParCSRMatrixOffd(A));
1507 HYPRE_Int *I = hypre_CSRMatrixI(M);
1508 int size = hypre_CSRMatrixNumRows(M) + 1;
1514 HYPRE_Int *J = hypre_CSRMatrixJ(M);
1515 int size = hypre_CSRMatrixNumNonzeros(M);
1519 void HypreParMatrix::Destroy()
1521 if ( X != NULL ) {
delete X; }
1522 if ( Y != NULL ) {
delete Y; }
1524 if (A == NULL) {
return; }
1533 hypre_CSRMatrixI(A->diag) = NULL;
1534 hypre_CSRMatrixJ(A->diag) = NULL;
1539 hypre_CSRMatrixData(A->diag) = NULL;
1548 hypre_CSRMatrixI(A->offd) = NULL;
1549 hypre_CSRMatrixJ(A->offd) = NULL;
1554 hypre_CSRMatrixData(A->offd) = NULL;
1556 if (colMapOwner >= 0)
1558 if (colMapOwner & 1)
1562 hypre_ParCSRMatrixColMapOffd(A) = NULL;
1567 hypre_ParCSRMatrixDestroy(A);
1571 #if MFEM_HYPRE_VERSION < 21400
1576 hypre_ParCSRMatrix *C_hypre =
1577 internal::hypre_ParCSRMatrixAdd(const_cast<HypreParMatrix &>(A),
1578 const_cast<HypreParMatrix &>(B));
1579 MFEM_VERIFY(C_hypre,
"error in hypre_ParCSRMatrixAdd");
1581 hypre_MatvecCommPkgCreate(C_hypre);
1592 hypre_ParCSRMatrix * C = internal::hypre_ParCSRMatrixAdd(*A,*B);
1594 hypre_MatvecCommPkgCreate(C);
1601 HypreParMatrix *
Add(
double alpha,
const HypreParMatrix &A,
1602 double beta,
const HypreParMatrix &B)
1604 hypre_ParCSRMatrix *C;
1605 hypre_ParcsrAdd(alpha, A, beta, B, &C);
1606 hypre_MatvecCommPkgCreate(C);
1608 return new HypreParMatrix(C);
1611 HypreParMatrix *
ParAdd(
const HypreParMatrix *A,
const HypreParMatrix *B)
1613 hypre_ParCSRMatrix *C;
1614 hypre_ParcsrAdd(1.0, *A, 1.0, *B, &C);
1616 hypre_MatvecCommPkgCreate(C);
1618 return new HypreParMatrix(C);
1626 hypre_ParCSRMatrix * ab;
1627 ab = hypre_ParMatmul(*A,*B);
1628 hypre_ParCSRMatrixSetNumNonzeros(ab);
1630 hypre_MatvecCommPkgCreate(ab);
1642 HYPRE_Int P_owns_its_col_starts =
1643 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
1645 hypre_ParCSRMatrix * rap;
1646 hypre_BoomerAMGBuildCoarseOperator(*P,*A,*P,&rap);
1647 hypre_ParCSRMatrixSetNumNonzeros(rap);
1652 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
1653 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
1655 if (P_owns_its_col_starts)
1657 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
1666 HYPRE_Int P_owns_its_col_starts =
1667 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
1668 HYPRE_Int Rt_owns_its_col_starts =
1669 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*Rt));
1671 hypre_ParCSRMatrix * rap;
1672 hypre_BoomerAMGBuildCoarseOperator(*Rt,*A,*P,&rap);
1674 hypre_ParCSRMatrixSetNumNonzeros(rap);
1679 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
1680 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
1682 if (P_owns_its_col_starts)
1684 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
1686 if (Rt_owns_its_col_starts)
1688 hypre_ParCSRMatrixSetColStartsOwner(*Rt, 1);
1697 const int num_loc,
const Array<int> &offsets,
1698 std::vector<int> &all_num_loc,
const int numBlocks,
1699 std::vector<std::vector<HYPRE_Int>> &blockProcOffsets,
1700 std::vector<HYPRE_Int> &procOffsets,
1701 std::vector<std::vector<int>> &procBlockOffsets,
1702 HYPRE_Int &firstLocal, HYPRE_Int &globalNum)
1704 std::vector<std::vector<int>> all_block_num_loc(numBlocks);
1706 MPI_Allgather(&num_loc, 1, MPI_INT, all_num_loc.data(), 1, MPI_INT, comm);
1708 for (
int j = 0; j < numBlocks; ++j)
1710 all_block_num_loc[j].resize(nprocs);
1711 blockProcOffsets[j].resize(nprocs);
1713 const int blockNumRows = offsets[j + 1] - offsets[j];
1714 MPI_Allgather(&blockNumRows, 1, MPI_INT, all_block_num_loc[j].data(), 1,
1716 blockProcOffsets[j][0] = 0;
1717 for (
int i = 0; i < nprocs - 1; ++i)
1719 blockProcOffsets[j][i + 1] = blockProcOffsets[j][i]
1720 + all_block_num_loc[j][i];
1727 for (
int i = 0; i < nprocs; ++i)
1729 globalNum += all_num_loc[i];
1732 MFEM_VERIFY(globalNum >= 0,
"overflow in global size");
1736 firstLocal += all_num_loc[i];
1741 procOffsets[i + 1] = procOffsets[i] + all_num_loc[i];
1744 procBlockOffsets[i].resize(numBlocks);
1745 procBlockOffsets[i][0] = 0;
1746 for (
int j = 1; j < numBlocks; ++j)
1748 procBlockOffsets[i][j] = procBlockOffsets[i][j - 1]
1749 + all_block_num_loc[j - 1][i];
1757 const int numBlockRows = blocks.
NumRows();
1758 const int numBlockCols = blocks.
NumCols();
1760 MFEM_VERIFY(numBlockRows > 0 &&
1761 numBlockCols > 0,
"Invalid input to HypreParMatrixFromBlocks");
1763 if (blockCoeff != NULL)
1765 MFEM_VERIFY(numBlockRows == blockCoeff->
NumRows() &&
1766 numBlockCols == blockCoeff->
NumCols(),
1767 "Invalid input to HypreParMatrixFromBlocks");
1773 int nonNullBlockRow0 = -1;
1774 for (
int j=0; j<numBlockCols; ++j)
1776 if (blocks(0,j) != NULL)
1778 nonNullBlockRow0 = j;
1783 MFEM_VERIFY(nonNullBlockRow0 >= 0,
"Null row of blocks");
1784 MPI_Comm comm = blocks(0,nonNullBlockRow0)->GetComm();
1789 for (
int i=0; i<numBlockRows; ++i)
1791 for (
int j=0; j<numBlockCols; ++j)
1793 if (blocks(i,j) != NULL)
1795 const int nrows = blocks(i,j)->
NumRows();
1796 const int ncols = blocks(i,j)->
NumCols();
1798 MFEM_VERIFY(nrows > 0 &&
1799 ncols > 0,
"Invalid block in HypreParMatrixFromBlocks");
1801 if (rowOffsets[i+1] == 0)
1803 rowOffsets[i+1] = nrows;
1807 MFEM_VERIFY(rowOffsets[i+1] == nrows,
1808 "Inconsistent blocks in HypreParMatrixFromBlocks");
1811 if (colOffsets[j+1] == 0)
1813 colOffsets[j+1] = ncols;
1817 MFEM_VERIFY(colOffsets[j+1] == ncols,
1818 "Inconsistent blocks in HypreParMatrixFromBlocks");
1823 MFEM_VERIFY(rowOffsets[i+1] > 0,
"Invalid input blocks");
1824 rowOffsets[i+1] += rowOffsets[i];
1827 for (
int j=0; j<numBlockCols; ++j)
1829 MFEM_VERIFY(colOffsets[j+1] > 0,
"Invalid input blocks");
1830 colOffsets[j+1] += colOffsets[j];
1833 const int num_loc_rows = rowOffsets[numBlockRows];
1834 const int num_loc_cols = colOffsets[numBlockCols];
1837 MPI_Comm_rank(comm, &rank);
1838 MPI_Comm_size(comm, &nprocs);
1840 std::vector<int> all_num_loc_rows(nprocs);
1841 std::vector<int> all_num_loc_cols(nprocs);
1842 std::vector<HYPRE_Int> procRowOffsets(nprocs);
1843 std::vector<HYPRE_Int> procColOffsets(nprocs);
1844 std::vector<std::vector<HYPRE_Int>> blockRowProcOffsets(numBlockRows);
1845 std::vector<std::vector<HYPRE_Int>> blockColProcOffsets(numBlockCols);
1846 std::vector<std::vector<int>> procBlockRowOffsets(nprocs);
1847 std::vector<std::vector<int>> procBlockColOffsets(nprocs);
1849 HYPRE_Int first_loc_row, glob_nrows, first_loc_col, glob_ncols;
1851 all_num_loc_rows, numBlockRows, blockRowProcOffsets,
1852 procRowOffsets, procBlockRowOffsets, first_loc_row,
1856 all_num_loc_cols, numBlockCols, blockColProcOffsets,
1857 procColOffsets, procBlockColOffsets, first_loc_col,
1860 std::vector<int> opI(num_loc_rows + 1);
1861 std::vector<int> cnt(num_loc_rows);
1863 for (
int i = 0; i < num_loc_rows; ++i)
1869 opI[num_loc_rows] = 0;
1874 for (
int i = 0; i < numBlockRows; ++i)
1876 for (
int j = 0; j < numBlockCols; ++j)
1878 if (blocks(i, j) == NULL)
1880 csr_blocks(i, j) = NULL;
1884 csr_blocks(i, j) = hypre_MergeDiagAndOffd(*blocks(i, j));
1886 for (
int k = 0; k < csr_blocks(i, j)->num_rows; ++k)
1888 opI[rowOffsets[i] + k + 1] +=
1889 csr_blocks(i, j)->i[k + 1] - csr_blocks(i, j)->i[k];
1896 for (
int i = 0; i < num_loc_rows; ++i)
1898 opI[i + 1] += opI[i];
1901 const int nnz = opI[num_loc_rows];
1903 std::vector<HYPRE_Int> opJ(nnz);
1904 std::vector<double> data(nnz);
1907 for (
int i = 0; i < numBlockRows; ++i)
1909 for (
int j = 0; j < numBlockCols; ++j)
1911 if (csr_blocks(i, j) != NULL)
1913 const int nrows = csr_blocks(i, j)->num_rows;
1914 const double cij = blockCoeff ? (*blockCoeff)(i, j) : 1.0;
1915 #if MFEM_HYPRE_VERSION >= 21600
1916 const bool usingBigJ = (csr_blocks(i, j)->big_j != NULL);
1919 for (
int k = 0; k < nrows; ++k)
1921 const int rowg = rowOffsets[i] + k;
1922 const int nnz_k = csr_blocks(i,j)->i[k+1]-csr_blocks(i,j)->i[k];
1923 const int osk = csr_blocks(i, j)->i[k];
1925 for (
int l = 0; l < nnz_k; ++l)
1928 #if MFEM_HYPRE_VERSION >= 21600
1929 const HYPRE_Int bcol = usingBigJ ?
1930 csr_blocks(i, j)->big_j[osk + l] :
1931 csr_blocks(i, j)->j[osk + l];
1933 const HYPRE_Int bcol = csr_blocks(i, j)->j[osk + l];
1937 const auto &offs = blockColProcOffsets[j];
1938 const int bcolproc =
1939 std::upper_bound(offs.begin() + 1, offs.end(), bcol)
1942 opJ[opI[rowg] + cnt[rowg]] = procColOffsets[bcolproc] +
1943 procBlockColOffsets[bcolproc][j]
1945 - blockColProcOffsets[j][bcolproc];
1946 data[opI[rowg] + cnt[rowg]] = cij * csr_blocks(i, j)->data[osk + l];
1954 for (
int i = 0; i < numBlockRows; ++i)
1956 for (
int j = 0; j < numBlockCols; ++j)
1958 if (csr_blocks(i, j) != NULL)
1960 hypre_CSRMatrixDestroy(csr_blocks(i, j));
1965 std::vector<HYPRE_Int> rowStarts2(2);
1966 rowStarts2[0] = first_loc_row;
1967 rowStarts2[1] = first_loc_row + all_num_loc_rows[rank];
1969 std::vector<HYPRE_Int> colStarts2(2);
1970 colStarts2[0] = first_loc_col;
1971 colStarts2[1] = first_loc_col + all_num_loc_cols[rank];
1973 MFEM_VERIFY(HYPRE_AssumedPartitionCheck(),
1974 "only 'assumed partition' mode is supported");
1976 return new HypreParMatrix(comm, num_loc_rows, glob_nrows, glob_ncols,
1977 opI.data(), opJ.data(), data.data(),
1978 rowStarts2.data(), colStarts2.data());
1986 Ae.
Mult(-1.0, X, 1.0, B);
1988 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag((hypre_ParCSRMatrix *)A);
1989 double *data = hypre_CSRMatrixData(A_diag);
1990 HYPRE_Int *I = hypre_CSRMatrixI(A_diag);
1992 HYPRE_Int *J = hypre_CSRMatrixJ(A_diag);
1993 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd((hypre_ParCSRMatrix *)A);
1994 HYPRE_Int *I_offd = hypre_CSRMatrixI(A_offd);
1995 double *data_offd = hypre_CSRMatrixData(A_offd);
1998 for (
int i = 0; i < ess_dof_list.
Size(); i++)
2000 int r = ess_dof_list[i];
2001 B(r) = data[I[r]] * X(r);
2008 MFEM_ABORT(
"the diagonal entry must be the first entry in the row!");
2010 for (
int j = I[r]+1; j < I[r+1]; j++)
2014 MFEM_ABORT(
"all off-diagonal entries must be zero!");
2017 for (
int j = I_offd[r]; j < I_offd[r+1]; j++)
2019 if (data_offd[j] != 0.0)
2021 MFEM_ABORT(
"all off-diagonal entries must be zero!");
2041 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
2042 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
2044 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(u));
2045 double *r_data = hypre_VectorData(hypre_ParVectorLocalVector(r));
2047 for (
int i = 0; i < N; i++)
2050 hypre_ParVectorCopy(f, r);
2051 hypre_ParCSRMatrixMatvec(-1.0, A, u, 1.0, r);
2054 (0 == (i % 2)) ? coef = lambda : coef =
mu;
2056 for (HYPRE_Int j = 0; j < num_rows; j++)
2058 u_data[j] += coef*r_data[j] / max_eig;
2074 hypre_ParVector *x0,
2075 hypre_ParVector *x1,
2076 hypre_ParVector *x2,
2077 hypre_ParVector *x3)
2080 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
2081 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
2083 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(u));
2085 double *x0_data = hypre_VectorData(hypre_ParVectorLocalVector(x0));
2086 double *x1_data = hypre_VectorData(hypre_ParVectorLocalVector(x1));
2087 double *x2_data = hypre_VectorData(hypre_ParVectorLocalVector(x2));
2088 double *x3_data = hypre_VectorData(hypre_ParVectorLocalVector(x3));
2090 hypre_ParVectorCopy(u, x0);
2093 hypre_ParVectorCopy(f, x1);
2094 hypre_ParCSRMatrixMatvec(-1.0, A, x0, 1.0, x1);
2096 for (HYPRE_Int i = 0; i < num_rows; i++)
2098 x1_data[i] /= -max_eig;
2102 for (HYPRE_Int i = 0; i < num_rows; i++)
2104 x1_data[i] = x0_data[i] -x1_data[i];
2108 for (HYPRE_Int i = 0; i < num_rows; i++)
2110 x3_data[i] = fir_coeffs[0]*x0_data[i] +fir_coeffs[1]*x1_data[i];
2113 for (
int n = 2; n <= poly_order; n++)
2116 hypre_ParVectorCopy(f, x2);
2117 hypre_ParCSRMatrixMatvec(-1.0, A, x1, 1.0, x2);
2119 for (HYPRE_Int i = 0; i < num_rows; i++)
2121 x2_data[i] /= -max_eig;
2129 for (HYPRE_Int i = 0; i < num_rows; i++)
2131 x2_data[i] = (x1_data[i]-x0_data[i]) +(x1_data[i]-2*x2_data[i]);
2132 x3_data[i] += fir_coeffs[n]*x2_data[i];
2133 x0_data[i] = x1_data[i];
2134 x1_data[i] = x2_data[i];
2138 for (HYPRE_Int i = 0; i < num_rows; i++)
2140 u_data[i] = x3_data[i];
2161 B =
X =
V =
Z = NULL;
2167 int _relax_times,
double _relax_weight,
double _omega,
2168 int _poly_order,
double _poly_fraction,
int _eig_est_cg_iter)
2180 B =
X =
V =
Z = NULL;
2189 type =
static_cast<int>(_type);
2200 int _eig_est_cg_iter)
2217 double a = -1,
b, c;
2218 if (!strcmp(name,
"Rectangular")) { a = 1.0,
b = 0.0, c = 0.0; }
2219 if (!strcmp(name,
"Hanning")) { a = 0.5,
b = 0.5, c = 0.0; }
2220 if (!strcmp(name,
"Hamming")) { a = 0.54,
b = 0.46, c = 0.0; }
2221 if (!strcmp(name,
"Blackman")) { a = 0.42,
b = 0.50, c = 0.08; }
2224 mfem_error(
"HypreSmoother::SetWindowByName : name not recognized!");
2242 mfem_error(
"HypreSmoother::SetOperator : not HypreParMatrix!");
2248 if (
B) {
delete B; }
2249 if (
X) {
delete X; }
2250 if (
V) {
delete V; }
2251 if (
Z) {
delete Z; }
2270 A->
Mult(ones, diag);
2278 for (
int i = 0; i <
height; i++)
2299 else if (
type == 1001 ||
type == 1002)
2338 double* window_coeffs =
new double[
poly_order+1];
2339 double* cheby_coeffs =
new double[
poly_order+1];
2347 window_coeffs[i] = a + b*cos(t) +c*cos(2*t);
2351 double theta_pb = acos(1.0 -0.5*k_pb);
2353 cheby_coeffs[0] = (theta_pb +
sigma)/M_PI;
2356 double t = i*(theta_pb+
sigma);
2357 cheby_coeffs[i] = 2.0*sin(t)/(i*M_PI);
2362 fir_coeffs[i] = window_coeffs[i]*cheby_coeffs[i];
2365 delete[] window_coeffs;
2366 delete[] cheby_coeffs;
2373 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
2383 HYPRE_ParCSRDiagScale(NULL, *
A, b, x);
2408 else if (
type == 1002)
2422 int hypre_type =
type;
2424 if (
type == 5) { hypre_type = 1; }
2427 hypre_ParCSRRelax(*
A, b, hypre_type,
2432 hypre_ParCSRRelax(*
A, b, hypre_type,
2443 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
2453 A -> GetGlobalNumRows(),
2454 const_cast<double*
>(b_data),
2455 A -> GetRowStarts());
2457 A -> GetGlobalNumCols(),
2459 A -> GetColStarts());
2463 B -> SetData(const_cast<double*>(b_data));
2464 X -> SetData(x_data);
2472 if (
B) {
delete B; }
2473 if (
X) {
delete X; }
2474 if (
V) {
delete V; }
2475 if (
Z) {
delete Z; }
2484 if (
X0) {
delete X0; }
2485 if (
X1) {
delete X1; }
2498 :
Solver(_A->Height(), _A->Width())
2511 mfem_error(
"HypreSolver::Mult (...) : HypreParMatrix A is missing");
2519 if (err) { MFEM_WARNING(
"Error during setup! Error code: " << err); }
2523 MFEM_VERIFY(!err,
"Error during setup! Error code: " << err);
2525 hypre_error_flag = 0;
2536 if (err) { MFEM_WARNING(
"Error during solve! Error code: " << err); }
2540 MFEM_VERIFY(!err,
"Error during solve! Error code: " << err);
2542 hypre_error_flag = 0;
2549 mfem_error(
"HypreSolver::Mult (...) : HypreParMatrix A is missing");
2557 A -> GetGlobalNumRows(),
2558 const_cast<double*
>(b_data),
2559 A -> GetRowStarts());
2561 A -> GetGlobalNumCols(),
2563 A -> GetColStarts());
2567 B -> SetData(const_cast<double*>(b_data));
2568 X -> SetData(x_data);
2576 if (
B) {
delete B; }
2577 if (
X) {
delete X; }
2585 HYPRE_ParCSRPCGCreate(comm, &pcg_solver);
2594 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2596 HYPRE_ParCSRPCGCreate(comm, &pcg_solver);
2602 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
2621 HYPRE_PCGSetTol(pcg_solver, tol);
2626 HYPRE_PCGSetMaxIter(pcg_solver, max_iter);
2631 HYPRE_PCGSetLogging(pcg_solver, logging);
2636 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_lvl);
2641 precond = &_precond;
2643 HYPRE_ParCSRPCGSetPrecond(pcg_solver,
2651 HYPRE_PCGSetTwoNorm(pcg_solver, 1);
2652 if (res_frequency > 0)
2654 HYPRE_PCGSetRecomputeResidualP(pcg_solver, res_frequency);
2658 HYPRE_PCGSetResidualTol(pcg_solver, rtol);
2665 HYPRE_Int time_index = 0;
2666 HYPRE_Int num_iterations;
2667 double final_res_norm;
2669 HYPRE_Int print_level;
2671 HYPRE_PCGGetPrintLevel(pcg_solver, &print_level);
2672 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level%3);
2674 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2678 if (print_level > 0 && print_level < 3)
2680 time_index = hypre_InitializeTiming(
"PCG Setup");
2681 hypre_BeginTiming(time_index);
2684 HYPRE_ParCSRPCGSetup(pcg_solver, *
A, b, x);
2687 if (print_level > 0 && print_level < 3)
2689 hypre_EndTiming(time_index);
2690 hypre_PrintTiming(
"Setup phase times", comm);
2691 hypre_FinalizeTiming(time_index);
2692 hypre_ClearTiming();
2696 if (print_level > 0 && print_level < 3)
2698 time_index = hypre_InitializeTiming(
"PCG Solve");
2699 hypre_BeginTiming(time_index);
2710 HYPRE_ParCSRPCGSolve(pcg_solver, *
A, b, x);
2712 if (print_level > 0)
2714 if (print_level < 3)
2716 hypre_EndTiming(time_index);
2717 hypre_PrintTiming(
"Solve phase times", comm);
2718 hypre_FinalizeTiming(time_index);
2719 hypre_ClearTiming();
2722 HYPRE_ParCSRPCGGetNumIterations(pcg_solver, &num_iterations);
2723 HYPRE_ParCSRPCGGetFinalRelativeResidualNorm(pcg_solver,
2726 MPI_Comm_rank(comm, &myid);
2730 mfem::out <<
"PCG Iterations = " << num_iterations << endl
2731 <<
"Final PCG Relative Residual Norm = " << final_res_norm
2735 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level);
2740 HYPRE_ParCSRPCGDestroy(pcg_solver);
2748 HYPRE_ParCSRGMRESCreate(comm, &gmres_solver);
2749 SetDefaultOptions();
2758 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2760 HYPRE_ParCSRGMRESCreate(comm, &gmres_solver);
2761 SetDefaultOptions();
2764 void HypreGMRES::SetDefaultOptions()
2770 HYPRE_ParCSRGMRESSetKDim(gmres_solver, k_dim);
2771 HYPRE_ParCSRGMRESSetMaxIter(gmres_solver, max_iter);
2772 HYPRE_ParCSRGMRESSetTol(gmres_solver, tol);
2778 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
2797 HYPRE_GMRESSetTol(gmres_solver, tol);
2802 HYPRE_GMRESSetMaxIter(gmres_solver, max_iter);
2807 HYPRE_GMRESSetKDim(gmres_solver, k_dim);
2812 HYPRE_GMRESSetLogging(gmres_solver, logging);
2817 HYPRE_GMRESSetPrintLevel(gmres_solver, print_lvl);
2822 precond = &_precond;
2824 HYPRE_ParCSRGMRESSetPrecond(gmres_solver,
2833 HYPRE_Int time_index = 0;
2834 HYPRE_Int num_iterations;
2835 double final_res_norm;
2837 HYPRE_Int print_level;
2839 HYPRE_GMRESGetPrintLevel(gmres_solver, &print_level);
2841 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2845 if (print_level > 0)
2847 time_index = hypre_InitializeTiming(
"GMRES Setup");
2848 hypre_BeginTiming(time_index);
2851 HYPRE_ParCSRGMRESSetup(gmres_solver, *
A, b, x);
2854 if (print_level > 0)
2856 hypre_EndTiming(time_index);
2857 hypre_PrintTiming(
"Setup phase times", comm);
2858 hypre_FinalizeTiming(time_index);
2859 hypre_ClearTiming();
2863 if (print_level > 0)
2865 time_index = hypre_InitializeTiming(
"GMRES Solve");
2866 hypre_BeginTiming(time_index);
2874 HYPRE_ParCSRGMRESSolve(gmres_solver, *
A, b, x);
2876 if (print_level > 0)
2878 hypre_EndTiming(time_index);
2879 hypre_PrintTiming(
"Solve phase times", comm);
2880 hypre_FinalizeTiming(time_index);
2881 hypre_ClearTiming();
2883 HYPRE_ParCSRGMRESGetNumIterations(gmres_solver, &num_iterations);
2884 HYPRE_ParCSRGMRESGetFinalRelativeResidualNorm(gmres_solver,
2887 MPI_Comm_rank(comm, &myid);
2891 mfem::out <<
"GMRES Iterations = " << num_iterations << endl
2892 <<
"Final GMRES Relative Residual Norm = " << final_res_norm
2900 HYPRE_ParCSRGMRESDestroy(gmres_solver);
2908 HYPRE_ParCSRFlexGMRESCreate(comm, &fgmres_solver);
2909 SetDefaultOptions();
2918 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2920 HYPRE_ParCSRFlexGMRESCreate(comm, &fgmres_solver);
2921 SetDefaultOptions();
2924 void HypreFGMRES::SetDefaultOptions()
2930 HYPRE_ParCSRFlexGMRESSetKDim(fgmres_solver, k_dim);
2931 HYPRE_ParCSRFlexGMRESSetMaxIter(fgmres_solver, max_iter);
2932 HYPRE_ParCSRFlexGMRESSetTol(fgmres_solver, tol);
2938 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
2957 HYPRE_ParCSRFlexGMRESSetTol(fgmres_solver, tol);
2962 HYPRE_ParCSRFlexGMRESSetMaxIter(fgmres_solver, max_iter);
2967 HYPRE_ParCSRFlexGMRESSetKDim(fgmres_solver, k_dim);
2972 HYPRE_ParCSRFlexGMRESSetLogging(fgmres_solver, logging);
2977 HYPRE_ParCSRFlexGMRESSetPrintLevel(fgmres_solver, print_lvl);
2982 precond = &_precond;
2983 HYPRE_ParCSRFlexGMRESSetPrecond(fgmres_solver,
2992 HYPRE_Int time_index = 0;
2993 HYPRE_Int num_iterations;
2994 double final_res_norm;
2996 HYPRE_Int print_level;
2998 HYPRE_FlexGMRESGetPrintLevel(fgmres_solver, &print_level);
3000 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
3004 if (print_level > 0)
3006 time_index = hypre_InitializeTiming(
"FGMRES Setup");
3007 hypre_BeginTiming(time_index);
3010 HYPRE_ParCSRFlexGMRESSetup(fgmres_solver, *
A, b, x);
3013 if (print_level > 0)
3015 hypre_EndTiming(time_index);
3016 hypre_PrintTiming(
"Setup phase times", comm);
3017 hypre_FinalizeTiming(time_index);
3018 hypre_ClearTiming();
3022 if (print_level > 0)
3024 time_index = hypre_InitializeTiming(
"FGMRES Solve");
3025 hypre_BeginTiming(time_index);
3033 HYPRE_ParCSRFlexGMRESSolve(fgmres_solver, *
A, b, x);
3035 if (print_level > 0)
3037 hypre_EndTiming(time_index);
3038 hypre_PrintTiming(
"Solve phase times", comm);
3039 hypre_FinalizeTiming(time_index);
3040 hypre_ClearTiming();
3042 HYPRE_ParCSRFlexGMRESGetNumIterations(fgmres_solver, &num_iterations);
3043 HYPRE_ParCSRFlexGMRESGetFinalRelativeResidualNorm(fgmres_solver,
3046 MPI_Comm_rank(comm, &myid);
3050 mfem::out <<
"FGMRES Iterations = " << num_iterations << endl
3051 <<
"Final FGMRES Relative Residual Norm = " << final_res_norm
3059 HYPRE_ParCSRFlexGMRESDestroy(fgmres_solver);
3066 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3081 HYPRE_ParaSailsCreate(comm, &sai_precond);
3082 SetDefaultOptions();
3089 HYPRE_ParCSRMatrixGetComm(A, &comm);
3091 HYPRE_ParaSailsCreate(comm, &sai_precond);
3092 SetDefaultOptions();
3095 void HypreParaSails::SetDefaultOptions()
3097 int sai_max_levels = 1;
3098 double sai_threshold = 0.1;
3099 double sai_filter = 0.1;
3101 double sai_loadbal = 0.0;
3103 int sai_logging = 1;
3105 HYPRE_ParaSailsSetParams(sai_precond, sai_threshold, sai_max_levels);
3106 HYPRE_ParaSailsSetFilter(sai_precond, sai_filter);
3107 HYPRE_ParaSailsSetSym(sai_precond, sai_sym);
3108 HYPRE_ParaSailsSetLoadbal(sai_precond, sai_loadbal);
3109 HYPRE_ParaSailsSetReuse(sai_precond, sai_reuse);
3110 HYPRE_ParaSailsSetLogging(sai_precond, sai_logging);
3113 void HypreParaSails::ResetSAIPrecond(MPI_Comm comm)
3115 HYPRE_Int sai_max_levels;
3116 HYPRE_Real sai_threshold;
3117 HYPRE_Real sai_filter;
3119 HYPRE_Real sai_loadbal;
3120 HYPRE_Int sai_reuse;
3121 HYPRE_Int sai_logging;
3124 HYPRE_ParaSailsGetNlevels(sai_precond, &sai_max_levels);
3125 HYPRE_ParaSailsGetThresh(sai_precond, &sai_threshold);
3126 HYPRE_ParaSailsGetFilter(sai_precond, &sai_filter);
3127 HYPRE_ParaSailsGetSym(sai_precond, &sai_sym);
3128 HYPRE_ParaSailsGetLoadbal(sai_precond, &sai_loadbal);
3129 HYPRE_ParaSailsGetReuse(sai_precond, &sai_reuse);
3130 HYPRE_ParaSailsGetLogging(sai_precond, &sai_logging);
3132 HYPRE_ParaSailsDestroy(sai_precond);
3133 HYPRE_ParaSailsCreate(comm, &sai_precond);
3135 HYPRE_ParaSailsSetParams(sai_precond, sai_threshold, sai_max_levels);
3136 HYPRE_ParaSailsSetFilter(sai_precond, sai_filter);
3137 HYPRE_ParaSailsSetSym(sai_precond, sai_sym);
3138 HYPRE_ParaSailsSetLoadbal(sai_precond, sai_loadbal);
3139 HYPRE_ParaSailsSetReuse(sai_precond, sai_reuse);
3140 HYPRE_ParaSailsSetLogging(sai_precond, sai_logging);
3146 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3151 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
3152 ResetSAIPrecond(comm);
3167 HYPRE_ParaSailsSetSym(sai_precond, sym);
3172 HYPRE_ParaSailsDestroy(sai_precond);
3178 HYPRE_EuclidCreate(comm, &euc_precond);
3179 SetDefaultOptions();
3186 HYPRE_ParCSRMatrixGetComm(A, &comm);
3188 HYPRE_EuclidCreate(comm, &euc_precond);
3189 SetDefaultOptions();
3192 void HypreEuclid::SetDefaultOptions()
3200 HYPRE_EuclidSetLevel(euc_precond, euc_level);
3201 HYPRE_EuclidSetStats(euc_precond, euc_stats);
3202 HYPRE_EuclidSetMem(euc_precond, euc_mem);
3203 HYPRE_EuclidSetBJ(euc_precond, euc_bj);
3204 HYPRE_EuclidSetRowScale(euc_precond, euc_ro_sc);
3207 void HypreEuclid::ResetEuclidPrecond(MPI_Comm comm)
3211 HYPRE_EuclidDestroy(euc_precond);
3212 HYPRE_EuclidCreate(comm, &euc_precond);
3214 SetDefaultOptions();
3220 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3225 HYPRE_ParCSRMatrixGetComm(*new_A, &comm);
3226 ResetEuclidPrecond(comm);
3241 HYPRE_EuclidDestroy(euc_precond);
3245 #if MFEM_HYPRE_VERSION >= 21900
3248 HYPRE_ILUCreate(&ilu_precond);
3249 SetDefaultOptions();
3252 void HypreILU::SetDefaultOptions()
3255 HYPRE_Int ilu_type = 0;
3256 HYPRE_ILUSetType(ilu_precond, ilu_type);
3259 HYPRE_Int max_iter = 1;
3260 HYPRE_ILUSetMaxIter(ilu_precond, max_iter);
3263 HYPRE_Real tol = 0.0;
3264 HYPRE_ILUSetTol(ilu_precond, tol);
3267 HYPRE_Int lev_fill = 1;
3268 HYPRE_ILUSetLevelOfFill(ilu_precond, lev_fill);
3271 HYPRE_Int reorder_type = 1;
3272 HYPRE_ILUSetLocalReordering(ilu_precond, reorder_type);
3275 HYPRE_Int print_level = 0;
3276 HYPRE_ILUSetPrintLevel(ilu_precond, print_level);
3279 void HypreILU::ResetILUPrecond()
3283 HYPRE_ILUDestroy(ilu_precond);
3285 HYPRE_ILUCreate(&ilu_precond);
3286 SetDefaultOptions();
3291 HYPRE_ILUSetLevelOfFill(ilu_precond, lev_fill);
3296 HYPRE_ILUSetPrintLevel(ilu_precond, print_level);
3302 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3304 if (
A) { ResetILUPrecond(); }
3318 HYPRE_ILUDestroy(ilu_precond);
3325 HYPRE_BoomerAMGCreate(&amg_precond);
3326 SetDefaultOptions();
3331 HYPRE_BoomerAMGCreate(&amg_precond);
3332 SetDefaultOptions();
3335 void HypreBoomerAMG::SetDefaultOptions()
3338 int coarsen_type = 10;
3340 double theta = 0.25;
3343 int interp_type = 6;
3348 int relax_sweeps = 1;
3351 int print_level = 1;
3352 int max_levels = 25;
3354 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
3355 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
3356 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
3357 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
3358 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
3359 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
3360 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
3361 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
3362 HYPRE_BoomerAMGSetMaxLevels(amg_precond, max_levels);
3365 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
3366 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
3369 void HypreBoomerAMG::ResetAMGPrecond()
3371 HYPRE_Int coarsen_type;
3372 HYPRE_Int agg_levels;
3373 HYPRE_Int relax_type;
3374 HYPRE_Int relax_sweeps;
3376 HYPRE_Int interp_type;
3378 HYPRE_Int print_level;
3380 HYPRE_Int nrbms = rbms.
Size();
3382 HYPRE_Int nodal_diag;
3383 HYPRE_Int relax_coarse;
3384 HYPRE_Int interp_vec_variant;
3386 HYPRE_Int smooth_interp_vectors;
3387 HYPRE_Int interp_refine;
3389 hypre_ParAMGData *amg_data = (hypre_ParAMGData *)amg_precond;
3392 HYPRE_BoomerAMGGetCoarsenType(amg_precond, &coarsen_type);
3393 agg_levels = hypre_ParAMGDataAggNumLevels(amg_data);
3394 relax_type = hypre_ParAMGDataUserRelaxType(amg_data);
3395 relax_sweeps = hypre_ParAMGDataUserNumSweeps(amg_data);
3396 HYPRE_BoomerAMGGetStrongThreshold(amg_precond, &theta);
3397 hypre_BoomerAMGGetInterpType(amg_precond, &interp_type);
3398 HYPRE_BoomerAMGGetPMaxElmts(amg_precond, &Pmax);
3399 HYPRE_BoomerAMGGetPrintLevel(amg_precond, &print_level);
3400 HYPRE_BoomerAMGGetNumFunctions(amg_precond, &dim);
3403 nodal = hypre_ParAMGDataNodal(amg_data);
3404 nodal_diag = hypre_ParAMGDataNodalDiag(amg_data);
3405 HYPRE_BoomerAMGGetCycleRelaxType(amg_precond, &relax_coarse, 3);
3406 interp_vec_variant = hypre_ParAMGInterpVecVariant(amg_data);
3407 q_max = hypre_ParAMGInterpVecQMax(amg_data);
3408 smooth_interp_vectors = hypre_ParAMGSmoothInterpVectors(amg_data);
3409 interp_refine = hypre_ParAMGInterpRefine(amg_data);
3412 HYPRE_BoomerAMGDestroy(amg_precond);
3413 HYPRE_BoomerAMGCreate(&amg_precond);
3415 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
3416 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
3417 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
3418 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
3419 HYPRE_BoomerAMGSetMaxLevels(amg_precond, 25);
3420 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
3421 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
3422 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
3423 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
3424 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
3425 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
3426 HYPRE_BoomerAMGSetNumFunctions(amg_precond, dim);
3429 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
3430 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
3431 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
3432 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
3433 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
3434 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
3435 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
3437 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
3444 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3446 if (
A) { ResetAMGPrecond(); }
3460 HYPRE_BoomerAMGSetNumFunctions(amg_precond, dim);
3469 HYPRE_Int *mapping = mfem_hypre_CTAlloc(HYPRE_Int,
height);
3471 MFEM_VERIFY(
height % dim == 0,
"Ordering does not work as claimed!");
3473 for (
int i = 0; i <
dim; ++i)
3475 for (
int j = 0; j < h_nnodes; ++j)
3480 HYPRE_BoomerAMGSetDofFunc(amg_precond, mapping);
3484 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, 0);
3485 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, 0.5);
3491 y = 0.0; y(0) = x(1); y(1) = -x(0);
3493 static void func_ryz(
const Vector &x, Vector &y)
3495 y = 0.0; y(1) = x(2); y(2) = -x(1);
3497 static void func_rzx(
const Vector &x, Vector &y)
3499 y = 0.0; y(2) = x(0); y(0) = -x(2);
3502 void HypreBoomerAMG::RecomputeRBMs()
3505 Array<HypreParVector*> gf_rbms;
3508 for (
int i = 0; i < rbms.
Size(); i++)
3510 HYPRE_ParVectorDestroy(rbms[i]);
3517 VectorFunctionCoefficient coeff_rxy(2, func_rxy);
3519 ParGridFunction rbms_rxy(fespace);
3520 rbms_rxy.ProjectCoefficient(coeff_rxy);
3523 gf_rbms.SetSize(nrbms);
3524 gf_rbms[0] = rbms_rxy.ParallelAverage();
3530 VectorFunctionCoefficient coeff_rxy(3, func_rxy);
3531 VectorFunctionCoefficient coeff_ryz(3, func_ryz);
3532 VectorFunctionCoefficient coeff_rzx(3, func_rzx);
3534 ParGridFunction rbms_rxy(fespace);
3535 ParGridFunction rbms_ryz(fespace);
3536 ParGridFunction rbms_rzx(fespace);
3537 rbms_rxy.ProjectCoefficient(coeff_rxy);
3538 rbms_ryz.ProjectCoefficient(coeff_ryz);
3539 rbms_rzx.ProjectCoefficient(coeff_rzx);
3542 gf_rbms.SetSize(nrbms);
3543 gf_rbms[0] = rbms_rxy.ParallelAverage();
3544 gf_rbms[1] = rbms_ryz.ParallelAverage();
3545 gf_rbms[2] = rbms_rzx.ParallelAverage();
3554 for (
int i = 0; i < nrbms; i++)
3556 rbms[i] = gf_rbms[i]->StealParVector();
3564 this->fespace = fespace;
3574 int relax_coarse = 8;
3577 int interp_vec_variant = 2;
3579 int smooth_interp_vectors = 1;
3583 int interp_refine = 1;
3585 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
3586 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
3587 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
3588 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
3589 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
3590 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
3591 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
3594 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
3605 for (
int i = 0; i < rbms.
Size(); i++)
3607 HYPRE_ParVectorDestroy(rbms[i]);
3610 HYPRE_BoomerAMGDestroy(amg_precond);
3626 int cycle_type = 13;
3629 double rlx_weight = 1.0;
3630 double rlx_omega = 1.0;
3631 int amg_coarsen_type = 10;
3632 int amg_agg_levels = 1;
3633 int amg_rlx_type = 8;
3634 double theta = 0.25;
3635 int amg_interp_type = 6;
3642 bool trace_space, rt_trace_space;
3646 trace_space = trace_space || rt_trace_space;
3649 if (edge_fespace->
GetNE() > 0)
3654 if (dim == 2) { p++; }
3665 nd_tr_fec =
new ND_Trace_FECollection(p, dim);
3666 edge_fespace =
new ParFiniteElementSpace(pmesh, nd_tr_fec);
3669 HYPRE_AMSCreate(&ams);
3671 HYPRE_AMSSetDimension(ams, sdim);
3672 HYPRE_AMSSetTol(ams, 0.0);
3673 HYPRE_AMSSetMaxIter(ams, 1);
3674 HYPRE_AMSSetCycleType(ams, cycle_type);
3675 HYPRE_AMSSetPrintLevel(ams, 1);
3678 FiniteElementCollection *vert_fec;
3681 vert_fec =
new H1_Trace_FECollection(p, dim);
3685 vert_fec =
new H1_FECollection(p, dim);
3687 ParFiniteElementSpace *vert_fespace =
new ParFiniteElementSpace(pmesh,
3693 ParGridFunction x_coord(vert_fespace);
3694 ParGridFunction y_coord(vert_fespace);
3695 ParGridFunction z_coord(vert_fespace);
3697 for (
int i = 0; i < pmesh->GetNV(); i++)
3699 coord = pmesh -> GetVertex(i);
3700 x_coord(i) = coord[0];
3701 y_coord(i) = coord[1];
3702 if (sdim == 3) { z_coord(i) = coord[2]; }
3704 x = x_coord.ParallelProject();
3705 y = y_coord.ParallelProject();
3709 HYPRE_AMSSetCoordinateVectors(ams, *x, *y, NULL);
3713 z = z_coord.ParallelProject();
3714 HYPRE_AMSSetCoordinateVectors(ams, *x, *y, *z);
3725 ParDiscreteLinearOperator *grad;
3726 grad =
new ParDiscreteLinearOperator(vert_fespace, edge_fespace);
3729 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
3733 grad->AddDomainInterpolator(
new GradientInterpolator);
3737 G = grad->ParallelAssemble();
3738 HYPRE_AMSSetDiscreteGradient(ams, *G);
3742 Pi = Pix = Piy = Piz = NULL;
3745 ParFiniteElementSpace *vert_fespace_d
3748 ParDiscreteLinearOperator *id_ND;
3749 id_ND =
new ParDiscreteLinearOperator(vert_fespace_d, edge_fespace);
3752 id_ND->AddTraceFaceInterpolator(
new IdentityInterpolator);
3756 id_ND->AddDomainInterpolator(
new IdentityInterpolator);
3761 if (cycle_type < 10)
3763 Pi = id_ND->ParallelAssemble();
3767 Array2D<HypreParMatrix *> Pi_blocks;
3768 id_ND->GetParBlocks(Pi_blocks);
3769 Pix = Pi_blocks(0,0);
3770 Piy = Pi_blocks(0,1);
3771 if (sdim == 3) { Piz = Pi_blocks(0,2); }
3776 HYPRE_ParCSRMatrix HY_Pi = (Pi) ? (HYPRE_ParCSRMatrix) *Pi : NULL;
3777 HYPRE_ParCSRMatrix HY_Pix = (Pix) ? (HYPRE_ParCSRMatrix) *Pix : NULL;
3778 HYPRE_ParCSRMatrix HY_Piy = (Piy) ? (HYPRE_ParCSRMatrix) *Piy : NULL;
3779 HYPRE_ParCSRMatrix HY_Piz = (Piz) ? (HYPRE_ParCSRMatrix) *Piz : NULL;
3780 HYPRE_AMSSetInterpolations(ams, HY_Pi, HY_Pix, HY_Piy, HY_Piz);
3782 delete vert_fespace_d;
3785 delete vert_fespace;
3790 delete edge_fespace;
3795 HYPRE_AMSSetSmoothingOptions(ams, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
3796 HYPRE_AMSSetAlphaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
3797 theta, amg_interp_type, amg_Pmax);
3798 HYPRE_AMSSetBetaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
3799 theta, amg_interp_type, amg_Pmax);
3811 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3826 HYPRE_AMSDestroy(ams);
3841 HYPRE_AMSSetPrintLevel(ams, print_lvl);
3857 int cycle_type = 11;
3860 double rlx_weight = 1.0;
3861 double rlx_omega = 1.0;
3862 int amg_coarsen_type = 10;
3863 int amg_agg_levels = 1;
3864 int amg_rlx_type = 8;
3865 double theta = 0.25;
3866 int amg_interp_type = 6;
3868 int ams_cycle_type = 14;
3874 if (face_fespace->
GetNE() > 0)
3886 HYPRE_ADSCreate(&ads);
3888 HYPRE_ADSSetTol(ads, 0.0);
3889 HYPRE_ADSSetMaxIter(ads, 1);
3890 HYPRE_ADSSetCycleType(ads, cycle_type);
3891 HYPRE_ADSSetPrintLevel(ads, 1);
3894 ParMesh *pmesh = (ParMesh *) face_fespace->
GetMesh();
3895 FiniteElementCollection *vert_fec, *edge_fec;
3898 vert_fec =
new H1_Trace_FECollection(p, 3);
3899 edge_fec =
new ND_Trace_FECollection(p, 3);
3903 vert_fec =
new H1_FECollection(p, 3);
3904 edge_fec =
new ND_FECollection(p, 3);
3907 ParFiniteElementSpace *vert_fespace =
new ParFiniteElementSpace(pmesh,
3909 ParFiniteElementSpace *edge_fespace =
new ParFiniteElementSpace(pmesh,
3915 ParGridFunction x_coord(vert_fespace);
3916 ParGridFunction y_coord(vert_fespace);
3917 ParGridFunction z_coord(vert_fespace);
3919 for (
int i = 0; i < pmesh->GetNV(); i++)
3921 coord = pmesh -> GetVertex(i);
3922 x_coord(i) = coord[0];
3923 y_coord(i) = coord[1];
3924 z_coord(i) = coord[2];
3926 x = x_coord.ParallelProject();
3927 y = y_coord.ParallelProject();
3928 z = z_coord.ParallelProject();
3929 HYPRE_ADSSetCoordinateVectors(ads, *x, *y, *z);
3939 ParDiscreteLinearOperator *curl;
3940 curl =
new ParDiscreteLinearOperator(edge_fespace, face_fespace);
3943 curl->AddTraceFaceInterpolator(
new CurlInterpolator);
3947 curl->AddDomainInterpolator(
new CurlInterpolator);
3951 C = curl->ParallelAssemble();
3953 HYPRE_ADSSetDiscreteCurl(ads, *C);
3957 ParDiscreteLinearOperator *grad;
3958 grad =
new ParDiscreteLinearOperator(vert_fespace, edge_fespace);
3961 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
3965 grad->AddDomainInterpolator(
new GradientInterpolator);
3969 G = grad->ParallelAssemble();
3972 HYPRE_ADSSetDiscreteGradient(ads, *G);
3976 RT_Pi = RT_Pix = RT_Piy = RT_Piz = NULL;
3977 ND_Pi = ND_Pix = ND_Piy = ND_Piz = NULL;
3980 ParFiniteElementSpace *vert_fespace_d
3983 ParDiscreteLinearOperator *id_ND;
3984 id_ND =
new ParDiscreteLinearOperator(vert_fespace_d, edge_fespace);
3987 id_ND->AddTraceFaceInterpolator(
new IdentityInterpolator);
3991 id_ND->AddDomainInterpolator(
new IdentityInterpolator);
3996 if (ams_cycle_type < 10)
3998 ND_Pi = id_ND->ParallelAssemble();
4004 Array2D<HypreParMatrix *> ND_Pi_blocks;
4005 id_ND->GetParBlocks(ND_Pi_blocks);
4006 ND_Pix = ND_Pi_blocks(0,0);
4007 ND_Piy = ND_Pi_blocks(0,1);
4008 ND_Piz = ND_Pi_blocks(0,2);
4013 ParDiscreteLinearOperator *id_RT;
4014 id_RT =
new ParDiscreteLinearOperator(vert_fespace_d, face_fespace);
4017 id_RT->AddTraceFaceInterpolator(
new NormalInterpolator);
4021 id_RT->AddDomainInterpolator(
new IdentityInterpolator);
4026 if (cycle_type < 10)
4028 RT_Pi = id_RT->ParallelAssemble();
4033 Array2D<HypreParMatrix *> RT_Pi_blocks;
4034 id_RT->GetParBlocks(RT_Pi_blocks);
4035 RT_Pix = RT_Pi_blocks(0,0);
4036 RT_Piy = RT_Pi_blocks(0,1);
4037 RT_Piz = RT_Pi_blocks(0,2);
4042 HYPRE_ParCSRMatrix HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz;
4043 HY_RT_Pi = (RT_Pi) ? (HYPRE_ParCSRMatrix) *RT_Pi : NULL;
4044 HY_RT_Pix = (RT_Pix) ? (HYPRE_ParCSRMatrix) *RT_Pix : NULL;
4045 HY_RT_Piy = (RT_Piy) ? (HYPRE_ParCSRMatrix) *RT_Piy : NULL;
4046 HY_RT_Piz = (RT_Piz) ? (HYPRE_ParCSRMatrix) *RT_Piz : NULL;
4047 HYPRE_ParCSRMatrix HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz;
4048 HY_ND_Pi = (ND_Pi) ? (HYPRE_ParCSRMatrix) *ND_Pi : NULL;
4049 HY_ND_Pix = (ND_Pix) ? (HYPRE_ParCSRMatrix) *ND_Pix : NULL;
4050 HY_ND_Piy = (ND_Piy) ? (HYPRE_ParCSRMatrix) *ND_Piy : NULL;
4051 HY_ND_Piz = (ND_Piz) ? (HYPRE_ParCSRMatrix) *ND_Piz : NULL;
4052 HYPRE_ADSSetInterpolations(ads,
4053 HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz,
4054 HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz);
4056 delete vert_fespace_d;
4060 delete vert_fespace;
4062 delete edge_fespace;
4065 HYPRE_ADSSetSmoothingOptions(ads, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
4066 HYPRE_ADSSetAMGOptions(ads, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
4067 theta, amg_interp_type, amg_Pmax);
4068 HYPRE_ADSSetAMSOptions(ads, ams_cycle_type, amg_coarsen_type, amg_agg_levels,
4069 amg_rlx_type, theta, amg_interp_type, amg_Pmax);
4081 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
4096 HYPRE_ADSDestroy(ads);
4118 HYPRE_ADSSetPrintLevel(ads, print_lvl);
4121 HypreLOBPCG::HypreMultiVector::HypreMultiVector(
int n,
HypreParVector & v,
4122 mv_InterfaceInterpreter & interpreter)
4126 mv_ptr = mv_MultiVectorCreateFromSampleVector(&interpreter, nv,
4127 (HYPRE_ParVector)v);
4129 HYPRE_ParVector* vecs = NULL;
4131 mv_TempMultiVector* tmp =
4132 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
4133 vecs = (HYPRE_ParVector*)(tmp -> vector);
4136 hpv =
new HypreParVector*[nv];
4137 for (
int i=0; i<nv; i++)
4139 hpv[i] =
new HypreParVector(vecs[i]);
4143 HypreLOBPCG::HypreMultiVector::~HypreMultiVector()
4147 for (
int i=0; i<nv; i++)
4154 mv_MultiVectorDestroy(mv_ptr);
4158 HypreLOBPCG::HypreMultiVector::Randomize(HYPRE_Int seed)
4160 mv_MultiVectorSetRandom(mv_ptr, seed);
4164 HypreLOBPCG::HypreMultiVector::GetVector(
unsigned int i)
4166 MFEM_ASSERT((
int)i < nv,
"index out of range");
4172 HypreLOBPCG::HypreMultiVector::StealVectors()
4174 HypreParVector ** hpv_ret = hpv;
4178 mv_TempMultiVector * mv_tmp =
4179 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
4181 mv_tmp->ownsVectors = 0;
4183 for (
int i=0; i<nv; i++)
4185 hpv_ret[i]->SetOwnership(1);
4203 MPI_Comm_size(comm,&numProcs);
4204 MPI_Comm_rank(comm,&myid);
4206 HYPRE_ParCSRSetupInterpreter(&interpreter);
4207 HYPRE_ParCSRSetupMatvec(&matvec_fn);
4208 HYPRE_LOBPCGCreate(&interpreter, &matvec_fn, &lobpcg_solver);
4217 HYPRE_LOBPCGDestroy(lobpcg_solver);
4223 HYPRE_LOBPCGSetTol(lobpcg_solver, tol);
4229 #if MFEM_HYPRE_VERSION >= 21101
4230 HYPRE_LOBPCGSetRTol(lobpcg_solver, rel_tol);
4232 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
4239 HYPRE_LOBPCGSetMaxIter(lobpcg_solver, max_iter);
4247 HYPRE_LOBPCGSetPrintLevel(lobpcg_solver, logging);
4254 HYPRE_LOBPCGSetPrecondUsageMode(lobpcg_solver, pcg_mode);
4260 HYPRE_LOBPCGSetPrecond(lobpcg_solver,
4261 (HYPRE_PtrToSolverFcn)this->PrecondSolve,
4262 (HYPRE_PtrToSolverFcn)this->PrecondSetup,
4263 (HYPRE_Solver)&precond);
4269 HYPRE_Int locSize = A.
Width();
4271 if (HYPRE_AssumedPartitionCheck())
4273 part =
new HYPRE_Int[2];
4275 MPI_Scan(&locSize, &part[1], 1, HYPRE_MPI_INT, MPI_SUM, comm);
4277 part[0] = part[1] - locSize;
4279 MPI_Allreduce(&locSize, &glbSize, 1, HYPRE_MPI_INT, MPI_SUM, comm);
4283 part =
new HYPRE_Int[numProcs+1];
4285 MPI_Allgather(&locSize, 1, HYPRE_MPI_INT,
4286 &part[1], 1, HYPRE_MPI_INT, comm);
4289 for (
int i=0; i<numProcs; i++)
4291 part[i+1] += part[i];
4294 glbSize = part[numProcs];
4305 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
4306 matvec_fn.Matvec = this->OperatorMatvec;
4307 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
4309 HYPRE_LOBPCGSetup(lobpcg_solver,(HYPRE_Matrix)&A,NULL,NULL);
4315 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
4316 matvec_fn.Matvec = this->OperatorMatvec;
4317 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
4319 HYPRE_LOBPCGSetupB(lobpcg_solver,(HYPRE_Matrix)&M,NULL);
4328 for (
int i=0; i<nev; i++)
4330 eigs[i] = eigenvalues[i];
4337 return multi_vec->GetVector(i);
4344 if ( multi_vec == NULL )
4346 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::SetInitialVectors()");
4348 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
4352 for (
int i=0; i < min(num_vecs,nev); i++)
4354 multi_vec->GetVector(i) = *vecs[i];
4358 for (
int i=min(num_vecs,nev); i < nev; i++)
4360 multi_vec->GetVector(i).Randomize(seed);
4364 if ( subSpaceProj != NULL )
4367 y = multi_vec->GetVector(0);
4369 for (
int i=1; i<nev; i++)
4371 subSpaceProj->
Mult(multi_vec->GetVector(i),
4372 multi_vec->GetVector(i-1));
4374 subSpaceProj->
Mult(y,
4375 multi_vec->GetVector(nev-1));
4383 if ( multi_vec == NULL )
4385 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::Solve()");
4387 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
4388 multi_vec->Randomize(seed);
4390 if ( subSpaceProj != NULL )
4393 y = multi_vec->GetVector(0);
4395 for (
int i=1; i<nev; i++)
4397 subSpaceProj->
Mult(multi_vec->GetVector(i),
4398 multi_vec->GetVector(i-1));
4400 subSpaceProj->
Mult(y, multi_vec->GetVector(nev-1));
4411 HYPRE_LOBPCGSolve(lobpcg_solver, NULL, *multi_vec, eigenvalues);
4415 HypreLOBPCG::OperatorMatvecCreate(
void *A,
4422 return ( matvec_data );
4426 HypreLOBPCG::OperatorMatvec(
void *matvec_data,
4427 HYPRE_Complex
alpha,
4433 MFEM_VERIFY(alpha == 1.0 && beta == 0.0,
"values not supported");
4435 Operator *Aop = (Operator*)A;
4437 int width = Aop->Width();
4439 hypre_ParVector * xPar = (hypre_ParVector *)x;
4440 hypre_ParVector * yPar = (hypre_ParVector *)y;
4442 Vector xVec(xPar->local_vector->data, width);
4443 Vector yVec(yPar->local_vector->data, width);
4445 Aop->Mult( xVec, yVec );
4451 HypreLOBPCG::OperatorMatvecDestroy(
void *matvec_data )
4457 HypreLOBPCG::PrecondSolve(
void *solver,
4462 Solver *
PC = (Solver*)solver;
4463 Operator *OP = (Operator*)A;
4465 int width = OP->Width();
4467 hypre_ParVector * bPar = (hypre_ParVector *)b;
4468 hypre_ParVector * xPar = (hypre_ParVector *)x;
4470 Vector bVec(bPar->local_vector->data, width);
4471 Vector xVec(xPar->local_vector->data, width);
4473 PC->Mult( bVec, xVec );
4479 HypreLOBPCG::PrecondSetup(
void *solver,
4497 MPI_Comm_size(comm,&numProcs);
4498 MPI_Comm_rank(comm,&myid);
4500 HYPRE_AMECreate(&ame_solver);
4501 HYPRE_AMESetPrintLevel(ame_solver, 0);
4508 mfem_hypre_TFree(multi_vec);
4513 for (
int i=0; i<nev; i++)
4515 delete eigenvectors[i];
4518 delete [] eigenvectors;
4522 mfem_hypre_TFree(eigenvalues);
4525 HYPRE_AMEDestroy(ame_solver);
4533 HYPRE_AMESetBlockSize(ame_solver, nev);
4539 HYPRE_AMESetTol(ame_solver, tol);
4545 #if MFEM_HYPRE_VERSION >= 21101
4546 HYPRE_AMESetRTol(ame_solver, rel_tol);
4548 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
4555 HYPRE_AMESetMaxIter(ame_solver, max_iter);
4563 HYPRE_AMESetPrintLevel(ame_solver, logging);
4570 ams_precond = &precond;
4578 HYPRE_Solver ams_precond_ptr = (HYPRE_Solver)*ams_precond;
4580 ams_precond->
SetupFcn()(*ams_precond,A,NULL,NULL);
4582 HYPRE_AMESetAMSSolver(ame_solver, ams_precond_ptr);
4585 HYPRE_AMESetup(ame_solver);
4591 HYPRE_ParCSRMatrix parcsr_M = M;
4592 HYPRE_AMESetMassMatrix(ame_solver,(HYPRE_ParCSRMatrix)parcsr_M);
4598 HYPRE_AMESolve(ame_solver);
4605 eigs.
SetSize(nev); eigs = -1.0;
4607 if ( eigenvalues == NULL )
4610 HYPRE_AMEGetEigenvalues(ame_solver,&eigenvalues);
4614 for (
int i=0; i<nev; i++)
4616 eigs[i] = eigenvalues[i];
4621 HypreAME::createDummyVectors()
4623 if ( multi_vec == NULL )
4625 HYPRE_AMEGetEigenvectors(ame_solver,&multi_vec);
4628 eigenvectors =
new HypreParVector*[nev];
4629 for (
int i=0; i<nev; i++)
4631 eigenvectors[i] =
new HypreParVector(multi_vec[i]);
4640 if ( eigenvectors == NULL )
4642 this->createDummyVectors();
4645 return *eigenvectors[i];
4651 if ( eigenvectors == NULL )
4653 this->createDummyVectors();
4658 eigenvectors = NULL;
virtual ~HypreBoomerAMG()
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
int Size() const
Return the logical size of the array.
void EliminateRowsCols(const Array< int > &rows_cols, const HypreParVector &X, HypreParVector &B)
void delete_hypre_CSRMatrixData(hypre_CSRMatrix *M)
HypreADS(ParFiniteElementSpace *face_fespace)
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.
HypreEuclid(MPI_Comm comm)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Vector * GlobalVector() const
Returns the global vector in each processor.
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)
ParMesh * GetParMesh() const
void Print(const char *fname, HYPRE_Int offi=0, HYPRE_Int offj=0)
Prints the locally owned rows in parallel.
MPI_Comm GetComm()
MPI communicator.
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?
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
void MakeRef(const HypreParMatrix &master)
Make this HypreParMatrix a reference to 'master'.
void Read_IJMatrix(MPI_Comm comm, const char *fname)
Read a matrix saved as a HYPRE_IJMatrix.
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)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
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.
Issue warnings on hypre errors.
void SetPreconditioner(HypreSolver &precond)
int Size() const
Returns the size of the vector.
HypreILU()
Constructor; sets the default options.
int * GetI()
Return the array I.
HypreAMS(ParFiniteElementSpace *edge_fespace)
void SetPrintLevel(int print_lvl)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
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.
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B, bool own_matrix)
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).
virtual MFEM_DEPRECATED N_Vector ToNVector()
(DEPRECATED) Return a new wrapper SUNDIALS N_Vector of type SUNDIALS_NVEC_PARALLEL.
int Size_of_connections() const
double poly_fraction
Fraction of spectrum to smooth for polynomial relaxation.
void SetPrintLevel(int print_lvl)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
int poly_scale
Apply the polynomial smoother to A or D^{-1/2} A D^{-1/2}.
HypreFGMRES(MPI_Comm comm)
double * GetData()
Return the element data, i.e. the array A.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's FGMRES.
void SetWindowParameters(double a, double b, double c)
Set parameters for windowing function for FIR smoother.
HypreGMRES(MPI_Comm comm)
Vector & operator=(const double *v)
Copy Size() entries from v.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
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 AbsMultTranspose(double a, const Vector &x, double b, Vector &y) const
Computes y = a * |At| * x + b * y, using entry-wise absolute values of the transpose of matrix A...
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).
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
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.
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)
Convert a string to an int.
Abort on hypre errors (default in base class)
void SetLogging(int logging)
Arbitrary order H(curl)-trace finite elements defined on the interface between mesh elements (faces...
void GetBlocks(Array2D< HypreParMatrix * > &blocks, bool interleaved_rows=false, bool interleaved_cols=false) const
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve the linear system Ax=b.
HypreParaSails(MPI_Comm comm)
HYPRE_Int GlobalTrueVSize() const
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
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.
void delete_hypre_CSRMatrixI(hypre_CSRMatrix *M)
Ignore hypre errors (see e.g. HypreADS)
double relax_weight
Damping coefficient (usually <= 1)
void SetElasticityOptions(ParFiniteElementSpace *fespace)
void GetDiag(Vector &diag) const
Get the local diagonal of the matrix.
void Sort()
Sorts the array in ascending order. This requires operator< to be defined for T.
int Size() const
Returns the number of TYPE I elements.
void SetLevelOfFill(HYPRE_Int lev_fill)
Set the fill level for ILU(k); the default is k=1.
HypreParMatrix * A
The linear system matrix.
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)
void SetMaxIter(int max_iter)
void SetPolyOptions(int poly_order, double poly_fraction, int eig_est_cg_iter=10)
Set parameters for polynomial smoothing.
void SetSOROptions(double relax_weight, double omega)
Set SOR-related parameters.
int SpaceDimension() const
Wrapper for hypre's parallel vector class.
HypreParMatrix * EliminateCols(const Array< int > &cols)
double Norml1() const
Returns the l_1 norm of the vector.
int ParCSRRelax_Taubin(hypre_ParCSRMatrix *A, hypre_ParVector *f, double lambda, double mu, int N, double max_eig, hypre_ParVector *u, hypre_ParVector *r)
double p(const Vector &x, double t)
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...
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
void SetPrintLevel(int print_lvl)
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void Solve()
Solve the eigenproblem.
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.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
HypreParMatrix * ParAdd(const HypreParMatrix *A, const HypreParMatrix *B)
Returns the matrix A + B.
double max_eig_est
Maximal eigenvalue estimate for polynomial smoothing.
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.
void EliminateRows(const Array< int > &rows)
Eliminate rows from the diagonal and off-diagonal blocks of the matrix.
double * fir_coeffs
Combined coefficients for windowing and Chebyshev polynomials.
void Threshold(double threshold=0.0)
Remove values smaller in absolute value than some threshold.
double InnerProduct(HypreParVector *x, HypreParVector *y)
HYPRE_Int GlobalSize()
Returns the global number of rows.
void SetPrintLevel(HYPRE_Int print_level)
Set the print level: 0 = none, 1 = setup, 2 = solve, 3 = setup+solve.
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.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void GatherBlockOffsetData(MPI_Comm comm, const int rank, const int nprocs, const int num_loc, const Array< int > &offsets, std::vector< int > &all_num_loc, const int numBlocks, std::vector< std::vector< HYPRE_Int >> &blockProcOffsets, std::vector< HYPRE_Int > &procOffsets, std::vector< std::vector< int >> &procBlockOffsets, HYPRE_Int &firstLocal, HYPRE_Int &globalNum)
void SetMassMatrix(HypreParMatrix &M)
HYPRE_Int M() const
Returns the global number of rows.
void delete_hypre_CSRMatrixJ(hypre_CSRMatrix *M)
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.
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...
int eig_est_cg_iter
Number of CG iterations to determine eigenvalue estimates.
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.
ErrorMode error_mode
How to treat hypre errors.
double * HostWrite()
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
HypreParVector & operator=(double d)
Set constant values.
HYPRE_Int * GetTrueDofOffsets() const
const FiniteElementCollection * FEColl() const
void PrintCommPkg(std::ostream &out=mfem::out) const
Print information about the hypre_ParCSRCommPkg of the HypreParMatrix.
void delete_hypre_ParCSRMatrixColMapOffd(hypre_ParCSRMatrix *A)
Arbitrary order "H^{-1/2}-conforming" face finite elements defined on the interface between mesh elem...
hypre_ParCSRMatrix * StealData()
Changes the ownership of the the matrix.
void SetPrecondUsageMode(int pcg_mode)
void SetSystemsOptions(int dim, bool order_bynodes=false)
HypreParMatrix * A
The linear system matrix.
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.
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 AbsMult(double a, const Vector &x, double b, Vector &y) const
Computes y = a * |A| * x + b * y, using entry-wise absolute values of matrix A.
void Swap(SparseMatrix &other)
~HypreParVector()
Calls hypre's destroy function.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's PCG.
HypreParMatrix * HypreParMatrixFromBlocks(Array2D< HypreParMatrix * > &blocks, Array2D< double > *blockCoeff)
Returns a merged hypre matrix constructed from hypre matrix blocks.
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.
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.
double f(const Vector &p)
double sigma(const Vector &x)