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 ? (TargetT*) Memory<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);
195 if (size != y.
Size())
207 hypre_VectorData(hypre_ParVectorLocalVector(x)) = _data;
213 return hypre_ParVectorSetRandomValues(x,seed);
218 hypre_ParVectorPrint(x,fname);
225 hypre_ParVectorDestroy(x);
229 #ifdef MFEM_USE_SUNDIALS
233 MFEM_ASSERT(nv && N_VGetVectorID(nv) == SUNDIALS_NVEC_PARHYP,
235 N_VectorContent_ParHyp nv_c = (N_VectorContent_ParHyp)(nv->content);
236 MFEM_ASSERT(nv_c->own_parvector == SUNFALSE,
"invalid N_Vector");
237 nv_c->local_length = x->local_vector->size;
238 nv_c->global_length = x->global_size;
239 nv_c->comm = x->comm;
243 #endif // MFEM_USE_SUNDIALS
248 return hypre_ParVectorInnerProd(*x, *y);
253 return hypre_ParVectorInnerProd(x, y);
262 double loc_norm = vec.
Norml1();
263 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
267 double loc_norm = vec*vec;
268 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
274 for (
int i = 0; i < vec.
Size(); i++)
276 sum += pow(fabs(vec(i)), p);
278 MPI_Allreduce(&sum, &norm, 1, MPI_DOUBLE, MPI_SUM, comm);
279 norm = pow(norm, 1.0/p);
284 MPI_Allreduce(&loc_norm, &norm, 1, MPI_DOUBLE, MPI_MAX, comm);
290 void HypreParMatrix::Init()
294 diagOwner = offdOwner = colMapOwner = -1;
304 char HypreParMatrix::CopyCSR(
SparseMatrix *csr, hypre_CSRMatrix *hypre_csr)
306 hypre_CSRMatrixData(hypre_csr) = csr->
GetData();
308 hypre_CSRMatrixI(hypre_csr) = csr->
GetI();
309 hypre_CSRMatrixJ(hypre_csr) = csr->
GetJ();
313 hypre_CSRMatrixI(hypre_csr) =
314 DuplicateAs<HYPRE_Int>(csr->
GetI(), csr->
Height()+1);
315 hypre_CSRMatrixJ(hypre_csr) =
322 char HypreParMatrix::CopyBoolCSR(Table *bool_csr, hypre_CSRMatrix *hypre_csr)
324 int nnz = bool_csr->Size_of_connections();
325 double *data =
new double[nnz];
326 for (
int i = 0; i < nnz; i++)
330 hypre_CSRMatrixData(hypre_csr) = data;
332 hypre_CSRMatrixI(hypre_csr) = bool_csr->GetI();
333 hypre_CSRMatrixJ(hypre_csr) = bool_csr->GetJ();
337 hypre_CSRMatrixI(hypre_csr) =
338 DuplicateAs<HYPRE_Int>(bool_csr->GetI(), bool_csr->Size()+1);
339 hypre_CSRMatrixJ(hypre_csr) =
340 DuplicateAs<HYPRE_Int>(bool_csr->GetJ(), nnz);
346 void HypreParMatrix::CopyCSR_J(hypre_CSRMatrix *hypre_csr,
int *J)
348 HYPRE_Int nnz = hypre_CSRMatrixNumNonzeros(hypre_csr);
349 for (HYPRE_Int j = 0; j < nnz; j++)
351 J[j] = int(hypre_CSRMatrixJ(hypre_csr)[j]);
358 :
Operator(diag->Height(), diag->Width())
361 A = hypre_ParCSRMatrixCreate(comm, glob_size, glob_size, row_starts,
363 hypre_ParCSRMatrixSetDataOwner(A,1);
364 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
365 hypre_ParCSRMatrixSetColStartsOwner(A,0);
367 hypre_CSRMatrixSetDataOwner(A->diag,0);
368 diagOwner = CopyCSR(diag, A->diag);
369 hypre_CSRMatrixSetRownnz(A->diag);
371 hypre_CSRMatrixSetDataOwner(A->offd,1);
372 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
379 hypre_ParCSRMatrixSetNumNonzeros(A);
382 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
384 CopyCSR_J(A->diag, diag->
GetJ());
387 hypre_MatvecCommPkgCreate(A);
392 HYPRE_Int global_num_rows,
393 HYPRE_Int global_num_cols,
394 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
396 :
Operator(diag->Height(), diag->Width())
399 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
400 row_starts, col_starts,
402 hypre_ParCSRMatrixSetDataOwner(A,1);
403 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
404 hypre_ParCSRMatrixSetColStartsOwner(A,0);
406 hypre_CSRMatrixSetDataOwner(A->diag,0);
407 diagOwner = CopyCSR(diag, A->diag);
408 hypre_CSRMatrixSetRownnz(A->diag);
410 hypre_CSRMatrixSetDataOwner(A->offd,1);
411 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Height()+1);
413 hypre_ParCSRMatrixSetNumNonzeros(A);
416 if (row_starts == col_starts)
418 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
420 CopyCSR_J(A->diag, diag->
GetJ());
424 hypre_MatvecCommPkgCreate(A);
429 HYPRE_Int global_num_rows,
430 HYPRE_Int global_num_cols,
431 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
434 :
Operator(diag->Height(), diag->Width())
437 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
438 row_starts, col_starts,
441 hypre_ParCSRMatrixSetDataOwner(A,1);
442 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
443 hypre_ParCSRMatrixSetColStartsOwner(A,0);
445 hypre_CSRMatrixSetDataOwner(A->diag,0);
446 diagOwner = CopyCSR(diag, A->diag);
447 hypre_CSRMatrixSetRownnz(A->diag);
449 hypre_CSRMatrixSetDataOwner(A->offd,0);
450 offdOwner = CopyCSR(offd, A->offd);
451 hypre_CSRMatrixSetRownnz(A->offd);
453 hypre_ParCSRMatrixColMapOffd(A) = cmap;
457 hypre_ParCSRMatrixSetNumNonzeros(A);
460 if (row_starts == col_starts)
462 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
464 CopyCSR_J(A->diag, diag->
GetJ());
468 hypre_MatvecCommPkgCreate(A);
474 HYPRE_Int global_num_rows, HYPRE_Int global_num_cols,
475 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
476 HYPRE_Int *diag_i, HYPRE_Int *diag_j,
double *diag_data,
477 HYPRE_Int *offd_i, HYPRE_Int *offd_j,
double *offd_data,
478 HYPRE_Int offd_num_cols, HYPRE_Int *offd_col_map)
481 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
482 row_starts, col_starts, offd_num_cols, 0, 0);
483 hypre_ParCSRMatrixSetDataOwner(A,1);
484 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
485 hypre_ParCSRMatrixSetColStartsOwner(A,0);
487 HYPRE_Int local_num_rows = hypre_CSRMatrixNumRows(A->diag);
489 hypre_CSRMatrixSetDataOwner(A->diag,0);
490 hypre_CSRMatrixI(A->diag) = diag_i;
491 hypre_CSRMatrixJ(A->diag) = diag_j;
492 hypre_CSRMatrixData(A->diag) = diag_data;
493 hypre_CSRMatrixNumNonzeros(A->diag) = diag_i[local_num_rows];
494 hypre_CSRMatrixSetRownnz(A->diag);
498 hypre_CSRMatrixSetDataOwner(A->offd,0);
499 hypre_CSRMatrixI(A->offd) = offd_i;
500 hypre_CSRMatrixJ(A->offd) = offd_j;
501 hypre_CSRMatrixData(A->offd) = offd_data;
502 hypre_CSRMatrixNumNonzeros(A->offd) = offd_i[local_num_rows];
503 hypre_CSRMatrixSetRownnz(A->offd);
507 hypre_ParCSRMatrixColMapOffd(A) = offd_col_map;
511 hypre_ParCSRMatrixSetNumNonzeros(A);
514 if (row_starts == col_starts)
516 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
519 hypre_MatvecCommPkgCreate(A);
527 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
530 MFEM_ASSERT(sm_a != NULL,
"invalid input");
531 MFEM_VERIFY(!HYPRE_AssumedPartitionCheck(),
532 "this method can not be used with assumed partition");
536 hypre_CSRMatrix *csr_a;
537 csr_a = hypre_CSRMatrixCreate(sm_a ->
Height(), sm_a ->
Width(),
538 sm_a -> NumNonZeroElems());
540 hypre_CSRMatrixSetDataOwner(csr_a,0);
541 CopyCSR(sm_a, csr_a);
542 hypre_CSRMatrixSetRownnz(csr_a);
544 A = hypre_CSRMatrixToParCSRMatrix(comm, csr_a, row_starts, col_starts);
547 delete [] hypre_CSRMatrixI(csr_a);
548 delete [] hypre_CSRMatrixJ(csr_a);
550 hypre_CSRMatrixI(csr_a) = NULL;
551 hypre_CSRMatrixDestroy(csr_a);
557 if (row_starts == col_starts)
559 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
562 hypre_MatvecCommPkgCreate(A);
567 HYPRE_Int global_num_rows,
568 HYPRE_Int global_num_cols,
569 HYPRE_Int *row_starts, HYPRE_Int *col_starts,
574 A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
575 row_starts, col_starts, 0, nnz, 0);
576 hypre_ParCSRMatrixSetDataOwner(A,1);
577 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
578 hypre_ParCSRMatrixSetColStartsOwner(A,0);
580 hypre_CSRMatrixSetDataOwner(A->diag,0);
581 diagOwner = CopyBoolCSR(diag, A->diag);
582 hypre_CSRMatrixSetRownnz(A->diag);
584 hypre_CSRMatrixSetDataOwner(A->offd,1);
585 hypre_CSRMatrixI(A->offd) = mfem_hypre_CTAlloc(HYPRE_Int, diag->
Size()+1);
587 hypre_ParCSRMatrixSetNumNonzeros(A);
590 if (row_starts == col_starts)
592 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
594 CopyCSR_J(A->diag, diag->
GetJ());
598 hypre_MatvecCommPkgCreate(A);
607 HYPRE_Int *row, HYPRE_Int *col,
608 HYPRE_Int *i_diag, HYPRE_Int *j_diag,
609 HYPRE_Int *i_offd, HYPRE_Int *j_offd,
610 HYPRE_Int *cmap, HYPRE_Int cmap_size)
612 HYPRE_Int diag_nnz, offd_nnz;
615 if (HYPRE_AssumedPartitionCheck())
617 diag_nnz = i_diag[row[1]-row[0]];
618 offd_nnz = i_offd[row[1]-row[0]];
620 A = hypre_ParCSRMatrixCreate(comm, row[2], col[2], row, col,
621 cmap_size, diag_nnz, offd_nnz);
625 diag_nnz = i_diag[row[
id+1]-row[id]];
626 offd_nnz = i_offd[row[
id+1]-row[id]];
628 A = hypre_ParCSRMatrixCreate(comm, row[np], col[np], row, col,
629 cmap_size, diag_nnz, offd_nnz);
632 hypre_ParCSRMatrixSetDataOwner(A,1);
633 hypre_ParCSRMatrixSetRowStartsOwner(A,0);
634 hypre_ParCSRMatrixSetColStartsOwner(A,0);
639 for (i = 0; i < diag_nnz; i++)
645 for (i = 0; i < offd_nnz; i++)
650 hypre_CSRMatrixSetDataOwner(A->diag,0);
651 hypre_CSRMatrixI(A->diag) = i_diag;
652 hypre_CSRMatrixJ(A->diag) = j_diag;
653 hypre_CSRMatrixData(A->diag) = a_diag;
654 hypre_CSRMatrixSetRownnz(A->diag);
658 hypre_CSRMatrixSetDataOwner(A->offd,0);
659 hypre_CSRMatrixI(A->offd) = i_offd;
660 hypre_CSRMatrixJ(A->offd) = j_offd;
661 hypre_CSRMatrixData(A->offd) = a_offd;
662 hypre_CSRMatrixSetRownnz(A->offd);
666 hypre_ParCSRMatrixColMapOffd(A) = cmap;
670 hypre_ParCSRMatrixSetNumNonzeros(A);
675 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
678 hypre_MatvecCommPkgCreate(A);
688 HYPRE_Int glob_ncols,
int *I, HYPRE_Int *J,
689 double *data, HYPRE_Int *rows, HYPRE_Int *cols)
695 HYPRE_Int my_col_start, my_col_end;
696 if (HYPRE_AssumedPartitionCheck())
699 my_col_start = cols[0];
700 my_col_end = cols[1];
705 MPI_Comm_rank(comm, &myid);
706 MPI_Comm_size(comm, &part_size);
708 my_col_start = cols[myid];
709 my_col_end = cols[myid+1];
713 HYPRE_Int *row_starts, *col_starts;
716 row_starts = col_starts = mfem_hypre_TAlloc(HYPRE_Int, part_size);
717 for (
int i = 0; i < part_size; i++)
719 row_starts[i] = rows[i];
724 row_starts = mfem_hypre_TAlloc(HYPRE_Int, part_size);
725 col_starts = mfem_hypre_TAlloc(HYPRE_Int, part_size);
726 for (
int i = 0; i < part_size; i++)
728 row_starts[i] = rows[i];
729 col_starts[i] = cols[i];
735 HYPRE_Int diag_nnz = 0, offd_nnz = 0, offd_num_cols = 0;
736 map<HYPRE_Int, HYPRE_Int> offd_map;
737 for (HYPRE_Int j = 0, loc_nnz = I[nrows]; j < loc_nnz; j++)
739 HYPRE_Int glob_col = J[j];
740 if (my_col_start <= glob_col && glob_col < my_col_end)
746 offd_map.insert(pair<const HYPRE_Int, HYPRE_Int>(glob_col, -1));
751 for (map<HYPRE_Int, HYPRE_Int>::iterator it = offd_map.begin();
752 it != offd_map.end(); ++it)
754 it->second = offd_num_cols++;
758 A = hypre_ParCSRMatrixCreate(comm, glob_nrows, glob_ncols,
759 row_starts, col_starts, offd_num_cols,
761 hypre_ParCSRMatrixInitialize(A);
763 HYPRE_Int *diag_i, *diag_j, *offd_i, *offd_j, *offd_col_map;
764 double *diag_data, *offd_data;
767 diag_data = A->diag->data;
770 offd_data = A->offd->data;
771 offd_col_map = A->col_map_offd;
773 diag_nnz = offd_nnz = 0;
774 for (HYPRE_Int i = 0, j = 0; i < nrows; i++)
776 diag_i[i] = diag_nnz;
777 offd_i[i] = offd_nnz;
778 for (HYPRE_Int j_end = I[i+1]; j < j_end; j++)
780 HYPRE_Int glob_col = J[j];
781 if (my_col_start <= glob_col && glob_col < my_col_end)
783 diag_j[diag_nnz] = glob_col - my_col_start;
784 diag_data[diag_nnz] = data[j];
789 offd_j[offd_nnz] = offd_map[glob_col];
790 offd_data[offd_nnz] = data[j];
795 diag_i[nrows] = diag_nnz;
796 offd_i[nrows] = offd_nnz;
797 for (map<HYPRE_Int, HYPRE_Int>::iterator it = offd_map.begin();
798 it != offd_map.end(); ++it)
800 offd_col_map[it->second] = it->first;
803 hypre_ParCSRMatrixSetNumNonzeros(A);
805 if (row_starts == col_starts)
807 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
809 hypre_MatvecCommPkgCreate(A);
817 hypre_ParCSRMatrix *Ph =
static_cast<hypre_ParCSRMatrix *
>(P);
822 A = hypre_ParCSRMatrixCompleteClone(Ph);
824 hypre_ParCSRMatrixCopy(Ph, A, 1);
832 hypre_ParCSRMatrixSetNumNonzeros(A);
834 hypre_MatvecCommPkgCreate(A);
852 MFEM_ASSERT(diagOwner == -1 && offdOwner == -1 && colMapOwner == -1,
"");
853 MFEM_ASSERT(ParCSROwner,
"");
854 hypre_ParCSRMatrix *R = A;
863 if (!A || hypre_ParCSRMatrixOwnsRowStarts(A) ||
864 (hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
865 hypre_ParCSRMatrixOwnsColStarts(A)))
871 if (HYPRE_AssumedPartitionCheck())
877 MPI_Comm_size(hypre_ParCSRMatrixComm(A), &row_starts_size);
881 HYPRE_Int *old_row_starts = hypre_ParCSRMatrixRowStarts(A);
882 HYPRE_Int *new_row_starts = mfem_hypre_CTAlloc(HYPRE_Int, row_starts_size);
883 for (
int i = 0; i < row_starts_size; i++)
885 new_row_starts[i] = old_row_starts[i];
888 hypre_ParCSRMatrixRowStarts(A) = new_row_starts;
889 hypre_ParCSRMatrixOwnsRowStarts(A) = 1;
891 if (hypre_ParCSRMatrixColStarts(A) == old_row_starts)
893 hypre_ParCSRMatrixColStarts(A) = new_row_starts;
894 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
900 if (!A || hypre_ParCSRMatrixOwnsColStarts(A) ||
901 (hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
902 hypre_ParCSRMatrixOwnsRowStarts(A)))
908 if (HYPRE_AssumedPartitionCheck())
914 MPI_Comm_size(hypre_ParCSRMatrixComm(A), &col_starts_size);
918 HYPRE_Int *old_col_starts = hypre_ParCSRMatrixColStarts(A);
919 HYPRE_Int *new_col_starts = mfem_hypre_CTAlloc(HYPRE_Int, col_starts_size);
920 for (
int i = 0; i < col_starts_size; i++)
922 new_col_starts[i] = old_col_starts[i];
925 hypre_ParCSRMatrixColStarts(A) = new_col_starts;
927 if (hypre_ParCSRMatrixRowStarts(A) == old_col_starts)
929 hypre_ParCSRMatrixRowStarts(A) = new_col_starts;
930 hypre_ParCSRMatrixOwnsRowStarts(A) = 1;
931 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
935 hypre_ParCSRMatrixOwnsColStarts(A) = 1;
943 for (
int j = 0; j < size; j++)
945 diag(j) = A->diag->data[A->diag->i[j]];
946 MFEM_ASSERT(A->diag->j[A->diag->i[j]] == j,
947 "the first entry in each row must be the diagonal one");
951 static void MakeWrapper(
const hypre_CSRMatrix *mat,
SparseMatrix &wrapper)
953 HYPRE_Int nr = hypre_CSRMatrixNumRows(mat);
954 HYPRE_Int nc = hypre_CSRMatrixNumCols(mat);
957 hypre_CSRMatrixJ(mat),
958 hypre_CSRMatrixData(mat),
959 nr, nc,
false,
false,
false);
961 HYPRE_Int nnz = hypre_CSRMatrixNumNonzeros(mat);
962 SparseMatrix tmp(DuplicateAs<int>(hypre_CSRMatrixI(mat), nr+1),
963 DuplicateAs<int>(hypre_CSRMatrixJ(mat), nnz),
964 hypre_CSRMatrixData(mat),
965 nr, nc,
true,
false,
false);
972 MakeWrapper(A->diag, diag);
977 MakeWrapper(A->offd, offd);
978 cmap = A->col_map_offd;
982 bool interleaved_rows,
983 bool interleaved_cols)
const
988 hypre_ParCSRMatrix **hypre_blocks =
new hypre_ParCSRMatrix*[nr * nc];
989 internal::hypre_ParCSRMatrixSplit(A, nr, nc, hypre_blocks,
990 interleaved_rows, interleaved_cols);
992 for (
int i = 0; i < nr; i++)
994 for (
int j = 0; j < nc; j++)
1000 delete [] hypre_blocks;
1005 hypre_ParCSRMatrix * At;
1006 hypre_ParCSRMatrixTranspose(A, &At, 1);
1007 hypre_ParCSRMatrixSetNumNonzeros(At);
1009 hypre_MatvecCommPkgCreate(At);
1015 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(At));
1026 return hypre_ParCSRMatrixMatvec(a, A, x, b, y);
1031 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1032 <<
", expected size = " <<
Width());
1033 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1034 <<
", expected size = " <<
Height());
1042 const_cast<double*>(x_data),
1051 X->
SetData(const_cast<double*>(x_data));
1055 hypre_ParCSRMatrixMatvec(a, A, *X, b, *Y);
1061 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
1062 <<
", expected size = " <<
Height());
1063 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
1064 <<
", expected size = " <<
Width());
1078 const_cast<double*>(x_data),
1084 Y->
SetData(const_cast<double*>(x_data));
1087 hypre_ParCSRMatrixMatvecT(a, A, *Y, b, *X);
1093 return hypre_ParCSRMatrixMatvec(a, A, (hypre_ParVector *) x, b,
1094 (hypre_ParVector *) y);
1100 return hypre_ParCSRMatrixMatvecT(a, A, x, b, y);
1104 HYPRE_Int* row_starts)
const
1106 const bool assumed_partition = HYPRE_AssumedPartitionCheck();
1107 const bool row_starts_given = (row_starts != NULL);
1108 if (!row_starts_given)
1110 row_starts = hypre_ParCSRMatrixRowStarts(A);
1111 MFEM_VERIFY(D.
Height() == hypre_CSRMatrixNumRows(A->diag),
1112 "the matrix D is NOT compatible with the row starts of"
1113 " this HypreParMatrix, row_starts must be given.");
1118 if (assumed_partition)
1124 MPI_Comm_rank(
GetComm(), &offset);
1126 int local_num_rows = row_starts[offset+1]-row_starts[offset];
1127 MFEM_VERIFY(local_num_rows == D.
Height(),
"the number of rows in D is "
1128 " not compatible with the given row_starts");
1134 HYPRE_Int global_num_rows;
1135 if (assumed_partition)
1138 if (row_starts_given)
1140 global_num_rows = row_starts[2];
1147 global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
1152 MPI_Comm_size(
GetComm(), &part_size);
1153 global_num_rows = row_starts[part_size];
1157 HYPRE_Int *col_starts = hypre_ParCSRMatrixColStarts(A);
1158 HYPRE_Int *col_map_offd;
1163 GetOffd(A_offd, col_map_offd);
1171 global_num_rows, hypre_ParCSRMatrixGlobalNumCols(A),
1172 DuplicateAs<HYPRE_Int>(row_starts, part_size,
false),
1173 DuplicateAs<HYPRE_Int>(col_starts, part_size,
false),
1175 DuplicateAs<HYPRE_Int>(col_map_offd, A_offd.
Width()));
1180 #ifndef HYPRE_BIGINT
1191 hypre_ParCSRMatrixSetRowStartsOwner(DA->A, 1);
1192 hypre_ParCSRMatrixSetColStartsOwner(DA->A, 1);
1194 DA->diagOwner = DA->offdOwner = 3;
1195 DA->colMapOwner = 1;
1202 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
1207 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
1209 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
1213 double *Adiag_data = hypre_CSRMatrixData(A->diag);
1214 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
1217 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
1218 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
1221 for (
int i(0); i < size; ++i)
1224 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
1226 Adiag_data[jj] *= val;
1228 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
1230 Aoffd_data[jj] *= val;
1237 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
1242 if (hypre_CSRMatrixNumRows(A->diag) != diag.
Size())
1244 mfem_error(
"Note the Vector diag is not of compatible dimensions with A\n");
1248 double *Adiag_data = hypre_CSRMatrixData(A->diag);
1249 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
1252 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
1253 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
1256 for (
int i(0); i < size; ++i)
1261 mfem_error(
"HypreParMatrix::InvDiagScale : Division by 0");
1265 for (jj = Adiag_i[i]; jj < Adiag_i[i+1]; ++jj)
1267 Adiag_data[jj] *= val;
1269 for (jj = Aoffd_i[i]; jj < Aoffd_i[i+1]; ++jj)
1271 Aoffd_data[jj] *= val;
1278 if (hypre_CSRMatrixNumRows(A->diag) != hypre_CSRMatrixNumRows(A->offd))
1283 HYPRE_Int size=hypre_CSRMatrixNumRows(A->diag);
1286 double *Adiag_data = hypre_CSRMatrixData(A->diag);
1287 HYPRE_Int *Adiag_i = hypre_CSRMatrixI(A->diag);
1288 for (jj = 0; jj < Adiag_i[size]; ++jj)
1290 Adiag_data[jj] *= s;
1293 double *Aoffd_data = hypre_CSRMatrixData(A->offd);
1294 HYPRE_Int *Aoffd_i = hypre_CSRMatrixI(A->offd);
1295 for (jj = 0; jj < Aoffd_i[size]; ++jj)
1297 Aoffd_data[jj] *= s;
1301 static void get_sorted_rows_cols(
const Array<int> &rows_cols,
1306 for (
int i = 0; i < rows_cols.
Size(); i++)
1308 hypre_sorted[i] = rows_cols[i];
1309 if (i && rows_cols[i-1] > rows_cols[i]) { sorted =
false; }
1311 if (!sorted) { hypre_sorted.
Sort(); }
1319 hypre_CSRMatrix * csr_A;
1320 hypre_CSRMatrix * csr_A_wo_z;
1321 hypre_ParCSRMatrix * parcsr_A_ptr;
1322 HYPRE_Int * row_starts = NULL; HYPRE_Int * col_starts = NULL;
1323 HYPRE_Int row_start = -1; HYPRE_Int row_end = -1;
1324 HYPRE_Int col_start = -1; HYPRE_Int col_end = -1;
1326 comm = hypre_ParCSRMatrixComm(A);
1328 ierr += hypre_ParCSRMatrixGetLocalRange(A,
1329 &row_start,&row_end,
1330 &col_start,&col_end );
1332 row_starts = hypre_ParCSRMatrixRowStarts(A);
1333 col_starts = hypre_ParCSRMatrixColStarts(A);
1335 bool old_owns_row = hypre_ParCSRMatrixOwnsRowStarts(A);
1336 bool old_owns_col = hypre_ParCSRMatrixOwnsColStarts(A);
1337 HYPRE_Int global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
1338 HYPRE_Int global_num_cols = hypre_ParCSRMatrixGlobalNumCols(A);
1339 parcsr_A_ptr = hypre_ParCSRMatrixCreate(comm, global_num_rows,
1341 row_starts, col_starts,
1343 hypre_ParCSRMatrixOwnsRowStarts(parcsr_A_ptr) = old_owns_row;
1344 hypre_ParCSRMatrixOwnsColStarts(parcsr_A_ptr) = old_owns_col;
1345 hypre_ParCSRMatrixOwnsRowStarts(A) = 0;
1346 hypre_ParCSRMatrixOwnsColStarts(A) = 0;
1348 csr_A = hypre_MergeDiagAndOffd(A);
1354 csr_A_wo_z = hypre_CSRMatrixDeleteZeros(csr_A,threshold);
1358 if (csr_A_wo_z == NULL)
1364 ierr += hypre_CSRMatrixDestroy(csr_A);
1370 ierr += GenerateDiagAndOffd(csr_A_wo_z,parcsr_A_ptr,
1373 ierr += hypre_CSRMatrixDestroy(csr_A_wo_z);
1375 MFEM_VERIFY(ierr == 0,
"");
1379 hypre_ParCSRMatrixSetNumNonzeros(A);
1381 if (row_starts == col_starts)
1383 hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
1385 hypre_MatvecCommPkgCreate(A);
1395 get_sorted_rows_cols(rows_cols, rc_sorted);
1397 internal::hypre_ParCSRMatrixEliminateAXB(
1404 get_sorted_rows_cols(rows_cols, rc_sorted);
1406 hypre_ParCSRMatrix* Ae;
1407 internal::hypre_ParCSRMatrixEliminateAAe(
1416 get_sorted_rows_cols(cols, rc_sorted);
1418 hypre_ParCSRMatrix* Ae;
1419 internal::hypre_ParCSRMatrixEliminateAAe(
1420 A, &Ae, rc_sorted.
Size(), rc_sorted.
GetData(), 1);
1427 if (rows.
Size() > 0)
1430 get_sorted_rows_cols(rows, r_sorted);
1431 internal::hypre_ParCSRMatrixEliminateRows(A, r_sorted.
Size(),
1438 hypre_ParCSRMatrixPrintIJ(A,offi,offj,fname);
1446 HYPRE_Int base_i, base_j;
1447 hypre_ParCSRMatrixReadIJ(comm, fname, &base_i, &base_j, &A);
1448 hypre_ParCSRMatrixSetNumNonzeros(A);
1450 hypre_MatvecCommPkgCreate(A);
1461 HYPRE_IJMatrix A_ij;
1462 HYPRE_IJMatrixRead(fname, comm, 5555, &A_ij);
1464 HYPRE_ParCSRMatrix A_parcsr;
1465 HYPRE_IJMatrixGetObject(A_ij, (
void**) &A_parcsr);
1467 A = (hypre_ParCSRMatrix*)A_parcsr;
1469 hypre_ParCSRMatrixSetNumNonzeros(A);
1471 hypre_MatvecCommPkgCreate(A);
1479 hypre_ParCSRCommPkg *comm_pkg = A->comm_pkg;
1480 MPI_Comm comm = A->comm;
1482 const int tag = 46801;
1484 MPI_Comm_rank(comm, &myid);
1485 MPI_Comm_size(comm, &nproc);
1489 MPI_Recv(&c, 1, MPI_CHAR, myid-1, tag, comm, MPI_STATUS_IGNORE);
1493 out <<
"\nHypreParMatrix: hypre_ParCSRCommPkg:\n";
1495 out <<
"Rank " << myid <<
":\n"
1496 " number of sends = " << comm_pkg->num_sends <<
1497 " (" <<
sizeof(double)*comm_pkg->send_map_starts[comm_pkg->num_sends] <<
1499 " number of recvs = " << comm_pkg->num_recvs <<
1500 " (" <<
sizeof(
double)*comm_pkg->recv_vec_starts[comm_pkg->num_recvs] <<
1502 if (myid != nproc-1)
1505 MPI_Send(&c, 1, MPI_CHAR, myid+1, tag, comm);
1516 HYPRE_Complex *data = hypre_CSRMatrixData(M);
1522 HYPRE_Int *A_col_map_offd = hypre_ParCSRMatrixColMapOffd(A);
1523 int size = hypre_CSRMatrixNumCols(hypre_ParCSRMatrixOffd(A));
1529 HYPRE_Int *I = hypre_CSRMatrixI(M);
1530 int size = hypre_CSRMatrixNumRows(M) + 1;
1536 HYPRE_Int *J = hypre_CSRMatrixJ(M);
1537 int size = hypre_CSRMatrixNumNonzeros(M);
1541 void HypreParMatrix::Destroy()
1543 if ( X != NULL ) {
delete X; }
1544 if ( Y != NULL ) {
delete Y; }
1546 if (A == NULL) {
return; }
1555 hypre_CSRMatrixI(A->diag) = NULL;
1556 hypre_CSRMatrixJ(A->diag) = NULL;
1561 hypre_CSRMatrixData(A->diag) = NULL;
1570 hypre_CSRMatrixI(A->offd) = NULL;
1571 hypre_CSRMatrixJ(A->offd) = NULL;
1576 hypre_CSRMatrixData(A->offd) = NULL;
1578 if (colMapOwner >= 0)
1580 if (colMapOwner & 1)
1584 hypre_ParCSRMatrixColMapOffd(A) = NULL;
1589 hypre_ParCSRMatrixDestroy(A);
1596 hypre_ParCSRMatrix *C_hypre =
1597 internal::hypre_ParCSRMatrixAdd(const_cast<HypreParMatrix &>(A),
1598 const_cast<HypreParMatrix &>(B));
1599 MFEM_VERIFY(C_hypre,
"error in hypre_ParCSRMatrixAdd");
1601 hypre_MatvecCommPkgCreate(C_hypre);
1613 hypre_ParCSRMatrix * ab;
1614 ab = hypre_ParMatmul(*A,*B);
1615 hypre_ParCSRMatrixSetNumNonzeros(ab);
1617 hypre_MatvecCommPkgCreate(ab);
1629 hypre_ParCSRMatrix * C = internal::hypre_ParCSRMatrixAdd(*A,*B);
1631 hypre_MatvecCommPkgCreate(C);
1638 HYPRE_Int P_owns_its_col_starts =
1639 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
1641 hypre_ParCSRMatrix * rap;
1642 hypre_BoomerAMGBuildCoarseOperator(*P,*A,*P,&rap);
1643 hypre_ParCSRMatrixSetNumNonzeros(rap);
1648 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
1649 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
1651 if (P_owns_its_col_starts)
1653 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
1662 HYPRE_Int P_owns_its_col_starts =
1663 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
1664 HYPRE_Int Rt_owns_its_col_starts =
1665 hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*Rt));
1667 hypre_ParCSRMatrix * rap;
1668 hypre_BoomerAMGBuildCoarseOperator(*Rt,*A,*P,&rap);
1670 hypre_ParCSRMatrixSetNumNonzeros(rap);
1675 hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
1676 hypre_ParCSRMatrixSetColStartsOwner(rap,0);
1678 if (P_owns_its_col_starts)
1680 hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
1682 if (Rt_owns_its_col_starts)
1684 hypre_ParCSRMatrixSetColStartsOwner(*Rt, 1);
1695 Ae.
Mult(-1.0, X, 1.0, B);
1697 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag((hypre_ParCSRMatrix *)A);
1698 double *data = hypre_CSRMatrixData(A_diag);
1699 HYPRE_Int *I = hypre_CSRMatrixI(A_diag);
1701 HYPRE_Int *J = hypre_CSRMatrixJ(A_diag);
1702 hypre_CSRMatrix *A_offd = hypre_ParCSRMatrixOffd((hypre_ParCSRMatrix *)A);
1703 HYPRE_Int *I_offd = hypre_CSRMatrixI(A_offd);
1704 double *data_offd = hypre_CSRMatrixData(A_offd);
1707 for (
int i = 0; i < ess_dof_list.
Size(); i++)
1709 int r = ess_dof_list[i];
1710 B(r) = data[I[r]] * X(r);
1717 MFEM_ABORT(
"the diagonal entry must be the first entry in the row!");
1719 for (
int j = I[r]+1; j < I[r+1]; j++)
1723 MFEM_ABORT(
"all off-diagonal entries must be zero!");
1726 for (
int j = I_offd[r]; j < I_offd[r+1]; j++)
1728 if (data_offd[j] != 0.0)
1730 MFEM_ABORT(
"all off-diagonal entries must be zero!");
1750 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
1751 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
1753 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(u));
1754 double *r_data = hypre_VectorData(hypre_ParVectorLocalVector(r));
1756 for (
int i = 0; i < N; i++)
1759 hypre_ParVectorCopy(f, r);
1760 hypre_ParCSRMatrixMatvec(-1.0, A, u, 1.0, r);
1763 (0 == (i % 2)) ? coef = lambda : coef = mu;
1765 for (HYPRE_Int j = 0; j < num_rows; j++)
1767 u_data[j] += coef*r_data[j] / max_eig;
1783 hypre_ParVector *x0,
1784 hypre_ParVector *x1,
1785 hypre_ParVector *x2,
1786 hypre_ParVector *x3)
1789 hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
1790 HYPRE_Int num_rows = hypre_CSRMatrixNumRows(A_diag);
1792 double *u_data = hypre_VectorData(hypre_ParVectorLocalVector(u));
1794 double *x0_data = hypre_VectorData(hypre_ParVectorLocalVector(x0));
1795 double *x1_data = hypre_VectorData(hypre_ParVectorLocalVector(x1));
1796 double *x2_data = hypre_VectorData(hypre_ParVectorLocalVector(x2));
1797 double *x3_data = hypre_VectorData(hypre_ParVectorLocalVector(x3));
1799 hypre_ParVectorCopy(u, x0);
1802 hypre_ParVectorCopy(f, x1);
1803 hypre_ParCSRMatrixMatvec(-1.0, A, x0, 1.0, x1);
1805 for (HYPRE_Int i = 0; i < num_rows; i++)
1807 x1_data[i] /= -max_eig;
1811 for (HYPRE_Int i = 0; i < num_rows; i++)
1813 x1_data[i] = x0_data[i] -x1_data[i];
1817 for (HYPRE_Int i = 0; i < num_rows; i++)
1819 x3_data[i] = fir_coeffs[0]*x0_data[i] +fir_coeffs[1]*x1_data[i];
1822 for (
int n = 2; n <= poly_order; n++)
1825 hypre_ParVectorCopy(f, x2);
1826 hypre_ParCSRMatrixMatvec(-1.0, A, x1, 1.0, x2);
1828 for (HYPRE_Int i = 0; i < num_rows; i++)
1830 x2_data[i] /= -max_eig;
1838 for (HYPRE_Int i = 0; i < num_rows; i++)
1840 x2_data[i] = (x1_data[i]-x0_data[i]) +(x1_data[i]-2*x2_data[i]);
1841 x3_data[i] += fir_coeffs[n]*x2_data[i];
1842 x0_data[i] = x1_data[i];
1843 x1_data[i] = x2_data[i];
1847 for (HYPRE_Int i = 0; i < num_rows; i++)
1849 u_data[i] = x3_data[i];
1869 B =
X =
V =
Z = NULL;
1875 int _relax_times,
double _relax_weight,
double _omega,
1876 int _poly_order,
double _poly_fraction)
1887 B =
X =
V =
Z = NULL;
1896 type =
static_cast<int>(_type);
1922 double a = -1,
b, c;
1923 if (!strcmp(name,
"Rectangular")) { a = 1.0,
b = 0.0, c = 0.0; }
1924 if (!strcmp(name,
"Hanning")) { a = 0.5,
b = 0.5, c = 0.0; }
1925 if (!strcmp(name,
"Hamming")) { a = 0.54,
b = 0.46, c = 0.0; }
1926 if (!strcmp(name,
"Blackman")) { a = 0.42,
b = 0.50, c = 0.08; }
1929 mfem_error(
"HypreSmoother::SetWindowByName : name not recognized!");
1947 mfem_error(
"HypreSmoother::SetOperator : not HypreParMatrix!");
1953 if (
B) {
delete B; }
1954 if (
X) {
delete X; }
1955 if (
V) {
delete V; }
1956 if (
Z) {
delete Z; }
1975 A->
Mult(ones, diag);
1984 for (
int i = 0; i <
height; i++)
1997 else if (
type == 1001 ||
type == 1002)
2028 double* window_coeffs =
new double[
poly_order+1];
2029 double* cheby_coeffs =
new double[
poly_order+1];
2037 window_coeffs[i] = a + b*cos(t) +c*cos(2*t);
2041 double theta_pb = acos(1.0 -0.5*k_pb);
2043 cheby_coeffs[0] = (theta_pb +
sigma)/M_PI;
2046 double t = i*(theta_pb+
sigma);
2047 cheby_coeffs[i] = 2.0*sin(t)/(i*M_PI);
2052 fir_coeffs[i] = window_coeffs[i]*cheby_coeffs[i];
2055 delete[] window_coeffs;
2056 delete[] cheby_coeffs;
2063 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
2073 HYPRE_ParCSRDiagScale(NULL, *
A, b, x);
2098 else if (
type == 1002)
2113 hypre_ParCSRRelax(*
A, b,
type,
2118 hypre_ParCSRRelax(*
A, b,
type,
2129 mfem_error(
"HypreSmoother::Mult (...) : HypreParMatrix A is missing");
2139 A -> GetGlobalNumRows(),
2140 const_cast<double*
>(b_data),
2141 A -> GetRowStarts());
2143 A -> GetGlobalNumCols(),
2145 A -> GetColStarts());
2149 B -> SetData(const_cast<double*>(b_data));
2150 X -> SetData(x_data);
2158 if (
B) {
delete B; }
2159 if (
X) {
delete X; }
2160 if (
V) {
delete V; }
2161 if (
Z) {
delete Z; }
2170 if (
X0) {
delete X0; }
2171 if (
X1) {
delete X1; }
2184 :
Solver(_A->Height(), _A->Width())
2197 mfem_error(
"HypreSolver::Mult (...) : HypreParMatrix A is missing");
2205 if (err) { MFEM_WARNING(
"Error during setup! Error code: " << err); }
2209 MFEM_VERIFY(!err,
"Error during setup! Error code: " << err);
2211 hypre_error_flag = 0;
2222 if (err) { MFEM_WARNING(
"Error during solve! Error code: " << err); }
2226 MFEM_VERIFY(!err,
"Error during solve! Error code: " << err);
2228 hypre_error_flag = 0;
2235 mfem_error(
"HypreSolver::Mult (...) : HypreParMatrix A is missing");
2243 A -> GetGlobalNumRows(),
2244 const_cast<double*
>(b_data),
2245 A -> GetRowStarts());
2247 A -> GetGlobalNumCols(),
2249 A -> GetColStarts());
2253 B -> SetData(const_cast<double*>(b_data));
2254 X -> SetData(x_data);
2262 if (
B) {
delete B; }
2263 if (
X) {
delete X; }
2271 HYPRE_ParCSRPCGCreate(comm, &pcg_solver);
2280 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2282 HYPRE_ParCSRPCGCreate(comm, &pcg_solver);
2288 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
2307 HYPRE_PCGSetTol(pcg_solver, tol);
2312 HYPRE_PCGSetMaxIter(pcg_solver, max_iter);
2317 HYPRE_PCGSetLogging(pcg_solver, logging);
2322 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_lvl);
2327 precond = &_precond;
2329 HYPRE_ParCSRPCGSetPrecond(pcg_solver,
2337 HYPRE_PCGSetTwoNorm(pcg_solver, 1);
2338 if (res_frequency > 0)
2340 HYPRE_PCGSetRecomputeResidualP(pcg_solver, res_frequency);
2344 HYPRE_PCGSetResidualTol(pcg_solver, rtol);
2351 HYPRE_Int time_index = 0;
2352 HYPRE_Int num_iterations;
2353 double final_res_norm;
2355 HYPRE_Int print_level;
2357 HYPRE_PCGGetPrintLevel(pcg_solver, &print_level);
2358 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level%3);
2360 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2364 if (print_level > 0 && print_level < 3)
2366 time_index = hypre_InitializeTiming(
"PCG Setup");
2367 hypre_BeginTiming(time_index);
2370 HYPRE_ParCSRPCGSetup(pcg_solver, *
A, b, x);
2373 if (print_level > 0 && print_level < 3)
2375 hypre_EndTiming(time_index);
2376 hypre_PrintTiming(
"Setup phase times", comm);
2377 hypre_FinalizeTiming(time_index);
2378 hypre_ClearTiming();
2382 if (print_level > 0 && print_level < 3)
2384 time_index = hypre_InitializeTiming(
"PCG Solve");
2385 hypre_BeginTiming(time_index);
2396 HYPRE_ParCSRPCGSolve(pcg_solver, *
A, b, x);
2398 if (print_level > 0)
2400 if (print_level < 3)
2402 hypre_EndTiming(time_index);
2403 hypre_PrintTiming(
"Solve phase times", comm);
2404 hypre_FinalizeTiming(time_index);
2405 hypre_ClearTiming();
2408 HYPRE_ParCSRPCGGetNumIterations(pcg_solver, &num_iterations);
2409 HYPRE_ParCSRPCGGetFinalRelativeResidualNorm(pcg_solver,
2412 MPI_Comm_rank(comm, &myid);
2416 mfem::out <<
"PCG Iterations = " << num_iterations << endl
2417 <<
"Final PCG Relative Residual Norm = " << final_res_norm
2421 HYPRE_ParCSRPCGSetPrintLevel(pcg_solver, print_level);
2426 HYPRE_ParCSRPCGDestroy(pcg_solver);
2434 HYPRE_ParCSRGMRESCreate(comm, &gmres_solver);
2435 SetDefaultOptions();
2444 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2446 HYPRE_ParCSRGMRESCreate(comm, &gmres_solver);
2447 SetDefaultOptions();
2450 void HypreGMRES::SetDefaultOptions()
2456 HYPRE_ParCSRGMRESSetKDim(gmres_solver, k_dim);
2457 HYPRE_ParCSRGMRESSetMaxIter(gmres_solver, max_iter);
2458 HYPRE_ParCSRGMRESSetTol(gmres_solver, tol);
2464 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
2483 HYPRE_GMRESSetTol(gmres_solver, tol);
2488 HYPRE_GMRESSetMaxIter(gmres_solver, max_iter);
2493 HYPRE_GMRESSetKDim(gmres_solver, k_dim);
2498 HYPRE_GMRESSetLogging(gmres_solver, logging);
2503 HYPRE_GMRESSetPrintLevel(gmres_solver, print_lvl);
2508 precond = &_precond;
2510 HYPRE_ParCSRGMRESSetPrecond(gmres_solver,
2519 HYPRE_Int time_index = 0;
2520 HYPRE_Int num_iterations;
2521 double final_res_norm;
2523 HYPRE_Int print_level;
2525 HYPRE_GMRESGetPrintLevel(gmres_solver, &print_level);
2527 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2531 if (print_level > 0)
2533 time_index = hypre_InitializeTiming(
"GMRES Setup");
2534 hypre_BeginTiming(time_index);
2537 HYPRE_ParCSRGMRESSetup(gmres_solver, *
A, b, x);
2540 if (print_level > 0)
2542 hypre_EndTiming(time_index);
2543 hypre_PrintTiming(
"Setup phase times", comm);
2544 hypre_FinalizeTiming(time_index);
2545 hypre_ClearTiming();
2549 if (print_level > 0)
2551 time_index = hypre_InitializeTiming(
"GMRES Solve");
2552 hypre_BeginTiming(time_index);
2560 HYPRE_ParCSRGMRESSolve(gmres_solver, *
A, b, x);
2562 if (print_level > 0)
2564 hypre_EndTiming(time_index);
2565 hypre_PrintTiming(
"Solve phase times", comm);
2566 hypre_FinalizeTiming(time_index);
2567 hypre_ClearTiming();
2569 HYPRE_ParCSRGMRESGetNumIterations(gmres_solver, &num_iterations);
2570 HYPRE_ParCSRGMRESGetFinalRelativeResidualNorm(gmres_solver,
2573 MPI_Comm_rank(comm, &myid);
2577 mfem::out <<
"GMRES Iterations = " << num_iterations << endl
2578 <<
"Final GMRES Relative Residual Norm = " << final_res_norm
2586 HYPRE_ParCSRGMRESDestroy(gmres_solver);
2593 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
2608 HYPRE_ParaSailsCreate(comm, &sai_precond);
2609 SetDefaultOptions();
2616 HYPRE_ParCSRMatrixGetComm(A, &comm);
2618 HYPRE_ParaSailsCreate(comm, &sai_precond);
2619 SetDefaultOptions();
2622 void HypreParaSails::SetDefaultOptions()
2624 int sai_max_levels = 1;
2625 double sai_threshold = 0.1;
2626 double sai_filter = 0.1;
2628 double sai_loadbal = 0.0;
2630 int sai_logging = 1;
2632 HYPRE_ParaSailsSetParams(sai_precond, sai_threshold, sai_max_levels);
2633 HYPRE_ParaSailsSetFilter(sai_precond, sai_filter);
2634 HYPRE_ParaSailsSetSym(sai_precond, sai_sym);
2635 HYPRE_ParaSailsSetLoadbal(sai_precond, sai_loadbal);
2636 HYPRE_ParaSailsSetReuse(sai_precond, sai_reuse);
2637 HYPRE_ParaSailsSetLogging(sai_precond, sai_logging);
2640 void HypreParaSails::ResetSAIPrecond(MPI_Comm comm)
2642 HYPRE_Int sai_max_levels;
2643 HYPRE_Real sai_threshold;
2644 HYPRE_Real sai_filter;
2646 HYPRE_Real sai_loadbal;
2647 HYPRE_Int sai_reuse;
2648 HYPRE_Int sai_logging;
2651 HYPRE_ParaSailsGetNlevels(sai_precond, &sai_max_levels);
2652 HYPRE_ParaSailsGetThresh(sai_precond, &sai_threshold);
2653 HYPRE_ParaSailsGetFilter(sai_precond, &sai_filter);
2654 HYPRE_ParaSailsGetSym(sai_precond, &sai_sym);
2655 HYPRE_ParaSailsGetLoadbal(sai_precond, &sai_loadbal);
2656 HYPRE_ParaSailsGetReuse(sai_precond, &sai_reuse);
2657 HYPRE_ParaSailsGetLogging(sai_precond, &sai_logging);
2659 HYPRE_ParaSailsDestroy(sai_precond);
2660 HYPRE_ParaSailsCreate(comm, &sai_precond);
2662 HYPRE_ParaSailsSetParams(sai_precond, sai_threshold, sai_max_levels);
2663 HYPRE_ParaSailsSetFilter(sai_precond, sai_filter);
2664 HYPRE_ParaSailsSetSym(sai_precond, sai_sym);
2665 HYPRE_ParaSailsSetLoadbal(sai_precond, sai_loadbal);
2666 HYPRE_ParaSailsSetReuse(sai_precond, sai_reuse);
2667 HYPRE_ParaSailsSetLogging(sai_precond, sai_logging);
2673 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
2678 HYPRE_ParCSRMatrixGetComm(*
A, &comm);
2679 ResetSAIPrecond(comm);
2694 HYPRE_ParaSailsSetSym(sai_precond, sym);
2699 HYPRE_ParaSailsDestroy(sai_precond);
2705 HYPRE_EuclidCreate(comm, &euc_precond);
2706 SetDefaultOptions();
2713 HYPRE_ParCSRMatrixGetComm(A, &comm);
2715 HYPRE_EuclidCreate(comm, &euc_precond);
2716 SetDefaultOptions();
2719 void HypreEuclid::SetDefaultOptions()
2727 HYPRE_EuclidSetLevel(euc_precond, euc_level);
2728 HYPRE_EuclidSetStats(euc_precond, euc_stats);
2729 HYPRE_EuclidSetMem(euc_precond, euc_mem);
2730 HYPRE_EuclidSetBJ(euc_precond, euc_bj);
2731 HYPRE_EuclidSetRowScale(euc_precond, euc_ro_sc);
2734 void HypreEuclid::ResetEuclidPrecond(MPI_Comm comm)
2738 HYPRE_EuclidDestroy(euc_precond);
2739 HYPRE_EuclidCreate(comm, &euc_precond);
2741 SetDefaultOptions();
2747 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
2752 HYPRE_ParCSRMatrixGetComm(*new_A, &comm);
2753 ResetEuclidPrecond(comm);
2768 HYPRE_EuclidDestroy(euc_precond);
2774 HYPRE_BoomerAMGCreate(&amg_precond);
2775 SetDefaultOptions();
2780 HYPRE_BoomerAMGCreate(&amg_precond);
2781 SetDefaultOptions();
2784 void HypreBoomerAMG::SetDefaultOptions()
2787 int coarsen_type = 10;
2789 double theta = 0.25;
2792 int interp_type = 6;
2797 int relax_sweeps = 1;
2800 int print_level = 1;
2801 int max_levels = 25;
2803 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
2804 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
2805 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
2806 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
2807 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
2808 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
2809 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
2810 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
2811 HYPRE_BoomerAMGSetMaxLevels(amg_precond, max_levels);
2814 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
2815 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
2818 void HypreBoomerAMG::ResetAMGPrecond()
2820 HYPRE_Int coarsen_type;
2821 HYPRE_Int agg_levels;
2822 HYPRE_Int relax_type;
2823 HYPRE_Int relax_sweeps;
2825 HYPRE_Int interp_type;
2827 HYPRE_Int print_level;
2829 HYPRE_Int nrbms = rbms.
Size();
2831 HYPRE_Int nodal_diag;
2832 HYPRE_Int relax_coarse;
2833 HYPRE_Int interp_vec_variant;
2835 HYPRE_Int smooth_interp_vectors;
2836 HYPRE_Int interp_refine;
2838 hypre_ParAMGData *amg_data = (hypre_ParAMGData *)amg_precond;
2841 HYPRE_BoomerAMGGetCoarsenType(amg_precond, &coarsen_type);
2842 agg_levels = hypre_ParAMGDataAggNumLevels(amg_data);
2843 relax_type = hypre_ParAMGDataUserRelaxType(amg_data);
2844 relax_sweeps = hypre_ParAMGDataUserNumSweeps(amg_data);
2845 HYPRE_BoomerAMGGetStrongThreshold(amg_precond, &theta);
2846 hypre_BoomerAMGGetInterpType(amg_precond, &interp_type);
2847 HYPRE_BoomerAMGGetPMaxElmts(amg_precond, &Pmax);
2848 HYPRE_BoomerAMGGetPrintLevel(amg_precond, &print_level);
2849 HYPRE_BoomerAMGGetNumFunctions(amg_precond, &dim);
2852 nodal = hypre_ParAMGDataNodal(amg_data);
2853 nodal_diag = hypre_ParAMGDataNodalDiag(amg_data);
2854 HYPRE_BoomerAMGGetCycleRelaxType(amg_precond, &relax_coarse, 3);
2855 interp_vec_variant = hypre_ParAMGInterpVecVariant(amg_data);
2856 q_max = hypre_ParAMGInterpVecQMax(amg_data);
2857 smooth_interp_vectors = hypre_ParAMGSmoothInterpVectors(amg_data);
2858 interp_refine = hypre_ParAMGInterpRefine(amg_data);
2861 HYPRE_BoomerAMGDestroy(amg_precond);
2862 HYPRE_BoomerAMGCreate(&amg_precond);
2864 HYPRE_BoomerAMGSetCoarsenType(amg_precond, coarsen_type);
2865 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, agg_levels);
2866 HYPRE_BoomerAMGSetRelaxType(amg_precond, relax_type);
2867 HYPRE_BoomerAMGSetNumSweeps(amg_precond, relax_sweeps);
2868 HYPRE_BoomerAMGSetMaxLevels(amg_precond, 25);
2869 HYPRE_BoomerAMGSetTol(amg_precond, 0.0);
2870 HYPRE_BoomerAMGSetMaxIter(amg_precond, 1);
2871 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, theta);
2872 HYPRE_BoomerAMGSetInterpType(amg_precond, interp_type);
2873 HYPRE_BoomerAMGSetPMaxElmts(amg_precond, Pmax);
2874 HYPRE_BoomerAMGSetPrintLevel(amg_precond, print_level);
2875 HYPRE_BoomerAMGSetNumFunctions(amg_precond, dim);
2878 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
2879 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
2880 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
2881 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
2882 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
2883 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
2884 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
2886 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
2893 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
2895 if (
A) { ResetAMGPrecond(); }
2909 HYPRE_BoomerAMGSetNumFunctions(amg_precond, dim);
2912 HYPRE_BoomerAMGSetAggNumLevels(amg_precond, 0);
2913 HYPRE_BoomerAMGSetStrongThreshold(amg_precond, 0.5);
2919 y = 0.0; y(0) = x(1); y(1) = -x(0);
2921 static void func_ryz(
const Vector &x, Vector &y)
2923 y = 0.0; y(1) = x(2); y(2) = -x(1);
2925 static void func_rzx(
const Vector &x, Vector &y)
2927 y = 0.0; y(2) = x(0); y(0) = -x(2);
2930 void HypreBoomerAMG::RecomputeRBMs()
2933 Array<HypreParVector*> gf_rbms;
2936 for (
int i = 0; i < rbms.
Size(); i++)
2938 HYPRE_ParVectorDestroy(rbms[i]);
2945 VectorFunctionCoefficient coeff_rxy(2, func_rxy);
2947 ParGridFunction rbms_rxy(fespace);
2948 rbms_rxy.ProjectCoefficient(coeff_rxy);
2951 gf_rbms.SetSize(nrbms);
2952 gf_rbms[0] = rbms_rxy.ParallelAverage();
2958 VectorFunctionCoefficient coeff_rxy(3, func_rxy);
2959 VectorFunctionCoefficient coeff_ryz(3, func_ryz);
2960 VectorFunctionCoefficient coeff_rzx(3, func_rzx);
2962 ParGridFunction rbms_rxy(fespace);
2963 ParGridFunction rbms_ryz(fespace);
2964 ParGridFunction rbms_rzx(fespace);
2965 rbms_rxy.ProjectCoefficient(coeff_rxy);
2966 rbms_ryz.ProjectCoefficient(coeff_ryz);
2967 rbms_rzx.ProjectCoefficient(coeff_rzx);
2970 gf_rbms.SetSize(nrbms);
2971 gf_rbms[0] = rbms_rxy.ParallelAverage();
2972 gf_rbms[1] = rbms_ryz.ParallelAverage();
2973 gf_rbms[2] = rbms_rzx.ParallelAverage();
2982 for (
int i = 0; i < nrbms; i++)
2984 rbms[i] = gf_rbms[i]->StealParVector();
2992 this->fespace = fespace;
3002 int relax_coarse = 8;
3005 int interp_vec_variant = 2;
3007 int smooth_interp_vectors = 1;
3011 int interp_refine = 1;
3013 HYPRE_BoomerAMGSetNodal(amg_precond, nodal);
3014 HYPRE_BoomerAMGSetNodalDiag(amg_precond, nodal_diag);
3015 HYPRE_BoomerAMGSetCycleRelaxType(amg_precond, relax_coarse, 3);
3016 HYPRE_BoomerAMGSetInterpVecVariant(amg_precond, interp_vec_variant);
3017 HYPRE_BoomerAMGSetInterpVecQMax(amg_precond, q_max);
3018 HYPRE_BoomerAMGSetSmoothInterpVectors(amg_precond, smooth_interp_vectors);
3019 HYPRE_BoomerAMGSetInterpRefine(amg_precond, interp_refine);
3022 HYPRE_BoomerAMGSetInterpVectors(amg_precond, rbms.
Size(), rbms.
GetData());
3033 for (
int i = 0; i < rbms.
Size(); i++)
3035 HYPRE_ParVectorDestroy(rbms[i]);
3038 HYPRE_BoomerAMGDestroy(amg_precond);
3054 int cycle_type = 13;
3057 double rlx_weight = 1.0;
3058 double rlx_omega = 1.0;
3059 int amg_coarsen_type = 10;
3060 int amg_agg_levels = 1;
3061 int amg_rlx_type = 8;
3062 double theta = 0.25;
3063 int amg_interp_type = 6;
3070 bool trace_space, rt_trace_space;
3074 trace_space = trace_space || rt_trace_space;
3077 if (edge_fespace->
GetNE() > 0)
3082 if (dim == 2) { p++; }
3093 nd_tr_fec =
new ND_Trace_FECollection(p, dim);
3094 edge_fespace =
new ParFiniteElementSpace(pmesh, nd_tr_fec);
3097 HYPRE_AMSCreate(&ams);
3099 HYPRE_AMSSetDimension(ams, sdim);
3100 HYPRE_AMSSetTol(ams, 0.0);
3101 HYPRE_AMSSetMaxIter(ams, 1);
3102 HYPRE_AMSSetCycleType(ams, cycle_type);
3103 HYPRE_AMSSetPrintLevel(ams, 1);
3106 FiniteElementCollection *vert_fec;
3109 vert_fec =
new H1_Trace_FECollection(p, dim);
3113 vert_fec =
new H1_FECollection(p, dim);
3115 ParFiniteElementSpace *vert_fespace =
new ParFiniteElementSpace(pmesh,
3121 ParGridFunction x_coord(vert_fespace);
3122 ParGridFunction y_coord(vert_fespace);
3123 ParGridFunction z_coord(vert_fespace);
3125 for (
int i = 0; i < pmesh->GetNV(); i++)
3127 coord = pmesh -> GetVertex(i);
3128 x_coord(i) = coord[0];
3129 y_coord(i) = coord[1];
3130 if (sdim == 3) { z_coord(i) = coord[2]; }
3132 x = x_coord.ParallelProject();
3133 y = y_coord.ParallelProject();
3137 HYPRE_AMSSetCoordinateVectors(ams, *x, *y, NULL);
3141 z = z_coord.ParallelProject();
3142 HYPRE_AMSSetCoordinateVectors(ams, *x, *y, *z);
3153 ParDiscreteLinearOperator *grad;
3154 grad =
new ParDiscreteLinearOperator(vert_fespace, edge_fespace);
3157 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
3161 grad->AddDomainInterpolator(
new GradientInterpolator);
3165 G = grad->ParallelAssemble();
3166 HYPRE_AMSSetDiscreteGradient(ams, *G);
3170 Pi = Pix = Piy = Piz = NULL;
3173 ParFiniteElementSpace *vert_fespace_d
3176 ParDiscreteLinearOperator *id_ND;
3177 id_ND =
new ParDiscreteLinearOperator(vert_fespace_d, edge_fespace);
3180 id_ND->AddTraceFaceInterpolator(
new IdentityInterpolator);
3184 id_ND->AddDomainInterpolator(
new IdentityInterpolator);
3189 if (cycle_type < 10)
3191 Pi = id_ND->ParallelAssemble();
3195 Array2D<HypreParMatrix *> Pi_blocks;
3196 id_ND->GetParBlocks(Pi_blocks);
3197 Pix = Pi_blocks(0,0);
3198 Piy = Pi_blocks(0,1);
3199 if (sdim == 3) { Piz = Pi_blocks(0,2); }
3204 HYPRE_ParCSRMatrix HY_Pi = (Pi) ? (HYPRE_ParCSRMatrix) *Pi : NULL;
3205 HYPRE_ParCSRMatrix HY_Pix = (Pix) ? (HYPRE_ParCSRMatrix) *Pix : NULL;
3206 HYPRE_ParCSRMatrix HY_Piy = (Piy) ? (HYPRE_ParCSRMatrix) *Piy : NULL;
3207 HYPRE_ParCSRMatrix HY_Piz = (Piz) ? (HYPRE_ParCSRMatrix) *Piz : NULL;
3208 HYPRE_AMSSetInterpolations(ams, HY_Pi, HY_Pix, HY_Piy, HY_Piz);
3210 delete vert_fespace_d;
3213 delete vert_fespace;
3218 delete edge_fespace;
3223 HYPRE_AMSSetSmoothingOptions(ams, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
3224 HYPRE_AMSSetAlphaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
3225 theta, amg_interp_type, amg_Pmax);
3226 HYPRE_AMSSetBetaAMGOptions(ams, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
3227 theta, amg_interp_type, amg_Pmax);
3239 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3254 HYPRE_AMSDestroy(ams);
3269 HYPRE_AMSSetPrintLevel(ams, print_lvl);
3285 int cycle_type = 11;
3288 double rlx_weight = 1.0;
3289 double rlx_omega = 1.0;
3290 int amg_coarsen_type = 10;
3291 int amg_agg_levels = 1;
3292 int amg_rlx_type = 8;
3293 double theta = 0.25;
3294 int amg_interp_type = 6;
3296 int ams_cycle_type = 14;
3302 if (face_fespace->
GetNE() > 0)
3314 HYPRE_ADSCreate(&ads);
3316 HYPRE_ADSSetTol(ads, 0.0);
3317 HYPRE_ADSSetMaxIter(ads, 1);
3318 HYPRE_ADSSetCycleType(ads, cycle_type);
3319 HYPRE_ADSSetPrintLevel(ads, 1);
3322 ParMesh *pmesh = (ParMesh *) face_fespace->
GetMesh();
3323 FiniteElementCollection *vert_fec, *edge_fec;
3326 vert_fec =
new H1_Trace_FECollection(p, 3);
3327 edge_fec =
new ND_Trace_FECollection(p, 3);
3331 vert_fec =
new H1_FECollection(p, 3);
3332 edge_fec =
new ND_FECollection(p, 3);
3335 ParFiniteElementSpace *vert_fespace =
new ParFiniteElementSpace(pmesh,
3337 ParFiniteElementSpace *edge_fespace =
new ParFiniteElementSpace(pmesh,
3343 ParGridFunction x_coord(vert_fespace);
3344 ParGridFunction y_coord(vert_fespace);
3345 ParGridFunction z_coord(vert_fespace);
3347 for (
int i = 0; i < pmesh->GetNV(); i++)
3349 coord = pmesh -> GetVertex(i);
3350 x_coord(i) = coord[0];
3351 y_coord(i) = coord[1];
3352 z_coord(i) = coord[2];
3354 x = x_coord.ParallelProject();
3355 y = y_coord.ParallelProject();
3356 z = z_coord.ParallelProject();
3357 HYPRE_ADSSetCoordinateVectors(ads, *x, *y, *z);
3367 ParDiscreteLinearOperator *curl;
3368 curl =
new ParDiscreteLinearOperator(edge_fespace, face_fespace);
3371 curl->AddTraceFaceInterpolator(
new CurlInterpolator);
3375 curl->AddDomainInterpolator(
new CurlInterpolator);
3379 C = curl->ParallelAssemble();
3381 HYPRE_ADSSetDiscreteCurl(ads, *C);
3385 ParDiscreteLinearOperator *grad;
3386 grad =
new ParDiscreteLinearOperator(vert_fespace, edge_fespace);
3389 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
3393 grad->AddDomainInterpolator(
new GradientInterpolator);
3397 G = grad->ParallelAssemble();
3400 HYPRE_ADSSetDiscreteGradient(ads, *G);
3404 RT_Pi = RT_Pix = RT_Piy = RT_Piz = NULL;
3405 ND_Pi = ND_Pix = ND_Piy = ND_Piz = NULL;
3408 ParFiniteElementSpace *vert_fespace_d
3411 ParDiscreteLinearOperator *id_ND;
3412 id_ND =
new ParDiscreteLinearOperator(vert_fespace_d, edge_fespace);
3415 id_ND->AddTraceFaceInterpolator(
new IdentityInterpolator);
3419 id_ND->AddDomainInterpolator(
new IdentityInterpolator);
3424 if (ams_cycle_type < 10)
3426 ND_Pi = id_ND->ParallelAssemble();
3432 Array2D<HypreParMatrix *> ND_Pi_blocks;
3433 id_ND->GetParBlocks(ND_Pi_blocks);
3434 ND_Pix = ND_Pi_blocks(0,0);
3435 ND_Piy = ND_Pi_blocks(0,1);
3436 ND_Piz = ND_Pi_blocks(0,2);
3441 ParDiscreteLinearOperator *id_RT;
3442 id_RT =
new ParDiscreteLinearOperator(vert_fespace_d, face_fespace);
3445 id_RT->AddTraceFaceInterpolator(
new NormalInterpolator);
3449 id_RT->AddDomainInterpolator(
new IdentityInterpolator);
3454 if (cycle_type < 10)
3456 RT_Pi = id_RT->ParallelAssemble();
3461 Array2D<HypreParMatrix *> RT_Pi_blocks;
3462 id_RT->GetParBlocks(RT_Pi_blocks);
3463 RT_Pix = RT_Pi_blocks(0,0);
3464 RT_Piy = RT_Pi_blocks(0,1);
3465 RT_Piz = RT_Pi_blocks(0,2);
3470 HYPRE_ParCSRMatrix HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz;
3471 HY_RT_Pi = (RT_Pi) ? (HYPRE_ParCSRMatrix) *RT_Pi : NULL;
3472 HY_RT_Pix = (RT_Pix) ? (HYPRE_ParCSRMatrix) *RT_Pix : NULL;
3473 HY_RT_Piy = (RT_Piy) ? (HYPRE_ParCSRMatrix) *RT_Piy : NULL;
3474 HY_RT_Piz = (RT_Piz) ? (HYPRE_ParCSRMatrix) *RT_Piz : NULL;
3475 HYPRE_ParCSRMatrix HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz;
3476 HY_ND_Pi = (ND_Pi) ? (HYPRE_ParCSRMatrix) *ND_Pi : NULL;
3477 HY_ND_Pix = (ND_Pix) ? (HYPRE_ParCSRMatrix) *ND_Pix : NULL;
3478 HY_ND_Piy = (ND_Piy) ? (HYPRE_ParCSRMatrix) *ND_Piy : NULL;
3479 HY_ND_Piz = (ND_Piz) ? (HYPRE_ParCSRMatrix) *ND_Piz : NULL;
3480 HYPRE_ADSSetInterpolations(ads,
3481 HY_RT_Pi, HY_RT_Pix, HY_RT_Piy, HY_RT_Piz,
3482 HY_ND_Pi, HY_ND_Pix, HY_ND_Piy, HY_ND_Piz);
3484 delete vert_fespace_d;
3488 delete vert_fespace;
3490 delete edge_fespace;
3493 HYPRE_ADSSetSmoothingOptions(ads, rlx_type, rlx_sweeps, rlx_weight, rlx_omega);
3494 HYPRE_ADSSetAMGOptions(ads, amg_coarsen_type, amg_agg_levels, amg_rlx_type,
3495 theta, amg_interp_type, amg_Pmax);
3496 HYPRE_ADSSetAMSOptions(ads, ams_cycle_type, amg_coarsen_type, amg_agg_levels,
3497 amg_rlx_type, theta, amg_interp_type, amg_Pmax);
3509 MFEM_VERIFY(new_A,
"new Operator must be a HypreParMatrix!");
3524 HYPRE_ADSDestroy(ads);
3546 HYPRE_ADSSetPrintLevel(ads, print_lvl);
3549 HypreLOBPCG::HypreMultiVector::HypreMultiVector(
int n,
HypreParVector & v,
3550 mv_InterfaceInterpreter & interpreter)
3554 mv_ptr = mv_MultiVectorCreateFromSampleVector(&interpreter, nv,
3555 (HYPRE_ParVector)v);
3557 HYPRE_ParVector* vecs = NULL;
3559 mv_TempMultiVector* tmp =
3560 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
3561 vecs = (HYPRE_ParVector*)(tmp -> vector);
3564 hpv =
new HypreParVector*[nv];
3565 for (
int i=0; i<nv; i++)
3567 hpv[i] =
new HypreParVector(vecs[i]);
3571 HypreLOBPCG::HypreMultiVector::~HypreMultiVector()
3575 for (
int i=0; i<nv; i++)
3582 mv_MultiVectorDestroy(mv_ptr);
3586 HypreLOBPCG::HypreMultiVector::Randomize(HYPRE_Int seed)
3588 mv_MultiVectorSetRandom(mv_ptr, seed);
3592 HypreLOBPCG::HypreMultiVector::GetVector(
unsigned int i)
3594 MFEM_ASSERT((
int)i < nv,
"index out of range");
3600 HypreLOBPCG::HypreMultiVector::StealVectors()
3602 HypreParVector ** hpv_ret = hpv;
3606 mv_TempMultiVector * mv_tmp =
3607 (mv_TempMultiVector*)mv_MultiVectorGetData(mv_ptr);
3609 mv_tmp->ownsVectors = 0;
3611 for (
int i=0; i<nv; i++)
3613 hpv_ret[i]->SetOwnership(1);
3631 MPI_Comm_size(comm,&numProcs);
3632 MPI_Comm_rank(comm,&myid);
3634 HYPRE_ParCSRSetupInterpreter(&interpreter);
3635 HYPRE_ParCSRSetupMatvec(&matvec_fn);
3636 HYPRE_LOBPCGCreate(&interpreter, &matvec_fn, &lobpcg_solver);
3645 HYPRE_LOBPCGDestroy(lobpcg_solver);
3651 HYPRE_LOBPCGSetTol(lobpcg_solver, tol);
3657 #if MFEM_HYPRE_VERSION >= 21101
3658 HYPRE_LOBPCGSetRTol(lobpcg_solver, rel_tol);
3660 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
3667 HYPRE_LOBPCGSetMaxIter(lobpcg_solver, max_iter);
3675 HYPRE_LOBPCGSetPrintLevel(lobpcg_solver, logging);
3682 HYPRE_LOBPCGSetPrecondUsageMode(lobpcg_solver, pcg_mode);
3688 HYPRE_LOBPCGSetPrecond(lobpcg_solver,
3689 (HYPRE_PtrToSolverFcn)this->PrecondSolve,
3690 (HYPRE_PtrToSolverFcn)this->PrecondSetup,
3691 (HYPRE_Solver)&precond);
3697 HYPRE_Int locSize = A.
Width();
3699 if (HYPRE_AssumedPartitionCheck())
3701 part =
new HYPRE_Int[2];
3703 MPI_Scan(&locSize, &part[1], 1, HYPRE_MPI_INT, MPI_SUM, comm);
3705 part[0] = part[1] - locSize;
3707 MPI_Allreduce(&locSize, &glbSize, 1, HYPRE_MPI_INT, MPI_SUM, comm);
3711 part =
new HYPRE_Int[numProcs+1];
3713 MPI_Allgather(&locSize, 1, HYPRE_MPI_INT,
3714 &part[1], 1, HYPRE_MPI_INT, comm);
3717 for (
int i=0; i<numProcs; i++)
3719 part[i+1] += part[i];
3722 glbSize = part[numProcs];
3733 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
3734 matvec_fn.Matvec = this->OperatorMatvec;
3735 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
3737 HYPRE_LOBPCGSetup(lobpcg_solver,(HYPRE_Matrix)&A,NULL,NULL);
3743 matvec_fn.MatvecCreate = this->OperatorMatvecCreate;
3744 matvec_fn.Matvec = this->OperatorMatvec;
3745 matvec_fn.MatvecDestroy = this->OperatorMatvecDestroy;
3747 HYPRE_LOBPCGSetupB(lobpcg_solver,(HYPRE_Matrix)&M,NULL);
3756 for (
int i=0; i<nev; i++)
3758 eigs[i] = eigenvalues[i];
3765 return multi_vec->GetVector(i);
3772 if ( multi_vec == NULL )
3774 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::SetInitialVectors()");
3776 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
3780 for (
int i=0; i < min(num_vecs,nev); i++)
3782 multi_vec->GetVector(i) = *vecs[i];
3786 for (
int i=min(num_vecs,nev); i < nev; i++)
3788 multi_vec->GetVector(i).Randomize(seed);
3792 if ( subSpaceProj != NULL )
3795 y = multi_vec->GetVector(0);
3797 for (
int i=1; i<nev; i++)
3799 subSpaceProj->
Mult(multi_vec->GetVector(i),
3800 multi_vec->GetVector(i-1));
3802 subSpaceProj->
Mult(y,
3803 multi_vec->GetVector(nev-1));
3811 if ( multi_vec == NULL )
3813 MFEM_ASSERT(x != NULL,
"In HypreLOBPCG::Solve()");
3815 multi_vec =
new HypreMultiVector(nev, *x, interpreter);
3816 multi_vec->Randomize(seed);
3818 if ( subSpaceProj != NULL )
3821 y = multi_vec->GetVector(0);
3823 for (
int i=1; i<nev; i++)
3825 subSpaceProj->
Mult(multi_vec->GetVector(i),
3826 multi_vec->GetVector(i-1));
3828 subSpaceProj->
Mult(y, multi_vec->GetVector(nev-1));
3839 HYPRE_LOBPCGSolve(lobpcg_solver, NULL, *multi_vec, eigenvalues);
3843 HypreLOBPCG::OperatorMatvecCreate(
void *A,
3850 return ( matvec_data );
3854 HypreLOBPCG::OperatorMatvec(
void *matvec_data,
3855 HYPRE_Complex
alpha,
3861 MFEM_VERIFY(alpha == 1.0 && beta == 0.0,
"values not supported");
3863 Operator *Aop = (Operator*)A;
3865 int width = Aop->Width();
3867 hypre_ParVector * xPar = (hypre_ParVector *)x;
3868 hypre_ParVector * yPar = (hypre_ParVector *)y;
3870 Vector xVec(xPar->local_vector->data, width);
3871 Vector yVec(yPar->local_vector->data, width);
3873 Aop->Mult( xVec, yVec );
3879 HypreLOBPCG::OperatorMatvecDestroy(
void *matvec_data )
3885 HypreLOBPCG::PrecondSolve(
void *solver,
3890 Solver *
PC = (Solver*)solver;
3891 Operator *OP = (Operator*)A;
3893 int width = OP->Width();
3895 hypre_ParVector * bPar = (hypre_ParVector *)b;
3896 hypre_ParVector * xPar = (hypre_ParVector *)x;
3898 Vector bVec(bPar->local_vector->data, width);
3899 Vector xVec(xPar->local_vector->data, width);
3901 PC->Mult( bVec, xVec );
3907 HypreLOBPCG::PrecondSetup(
void *solver,
3925 MPI_Comm_size(comm,&numProcs);
3926 MPI_Comm_rank(comm,&myid);
3928 HYPRE_AMECreate(&ame_solver);
3929 HYPRE_AMESetPrintLevel(ame_solver, 0);
3936 mfem_hypre_TFree(multi_vec);
3941 for (
int i=0; i<nev; i++)
3943 delete eigenvectors[i];
3946 delete [] eigenvectors;
3950 mfem_hypre_TFree(eigenvalues);
3953 HYPRE_AMEDestroy(ame_solver);
3961 HYPRE_AMESetBlockSize(ame_solver, nev);
3967 HYPRE_AMESetTol(ame_solver, tol);
3973 #if MFEM_HYPRE_VERSION >= 21101
3974 HYPRE_AMESetRTol(ame_solver, rel_tol);
3976 MFEM_ABORT(
"This method requires HYPRE version >= 2.11.1");
3983 HYPRE_AMESetMaxIter(ame_solver, max_iter);
3991 HYPRE_AMESetPrintLevel(ame_solver, logging);
3998 ams_precond = &precond;
4006 HYPRE_Solver ams_precond_ptr = (HYPRE_Solver)*ams_precond;
4008 ams_precond->
SetupFcn()(*ams_precond,A,NULL,NULL);
4010 HYPRE_AMESetAMSSolver(ame_solver, ams_precond_ptr);
4013 HYPRE_AMESetup(ame_solver);
4019 HYPRE_ParCSRMatrix parcsr_M = M;
4020 HYPRE_AMESetMassMatrix(ame_solver,(HYPRE_ParCSRMatrix)parcsr_M);
4026 HYPRE_AMESolve(ame_solver);
4033 eigs.
SetSize(nev); eigs = -1.0;
4035 if ( eigenvalues == NULL )
4038 HYPRE_AMEGetEigenvalues(ame_solver,&eigenvalues);
4042 for (
int i=0; i<nev; i++)
4044 eigs[i] = eigenvalues[i];
4049 HypreAME::createDummyVectors()
4051 if ( multi_vec == NULL )
4053 HYPRE_AMEGetEigenvectors(ame_solver,&multi_vec);
4056 eigenvectors =
new HypreParVector*[nev];
4057 for (
int i=0; i<nev; i++)
4059 eigenvectors[i] =
new HypreParVector(multi_vec[i]);
4068 if ( eigenvectors == NULL )
4070 this->createDummyVectors();
4073 return *eigenvectors[i];
4079 if ( eigenvectors == NULL )
4081 this->createDummyVectors();
4086 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)
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)
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?
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
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.
virtual N_Vector ToNVector()
Return a new wrapper SUNDIALS N_Vector of type SUNDIALS_NVEC_PARHYP.
int * GetI()
Return the array I.
HypreAMS(ParFiniteElementSpace *edge_fespace)
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.
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).
int Size_of_connections() const
double poly_fraction
Fraction of spectrum to smooth for polynomial relaxation.
void SetPrintLevel(int print_lvl)
int poly_scale
Apply the polynomial smoother to A or D^{-1/2} A D^{-1/2}.
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.
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 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).
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)
Abort on hypre errors (default in base class)
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. This requires operator< to be defined for T.
int Size() const
Returns the number of TYPE I elements.
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 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)
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.
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)
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 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.
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.
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)
hypre_ParCSRMatrix * StealData()
Changes the ownership of the the matrix.
void SetPrecondUsageMode(int pcg_mode)
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 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.
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 sigma(const Vector &x)