45 #include "Epetra_Map.h"
46 #include "Epetra_Vector.h"
47 #include "Epetra_MultiVector.h"
49 #include "Teuchos_RCP.hpp"
50 #include "Teuchos_Assert.hpp"
51 #include "Teuchos_Array.hpp"
65 TransposeSolve_(false),
68 IsSolverSetup_ =
new bool[1];
69 IsPrecondSetup_ =
new bool[1];
70 IsSolverSetup_[0] =
false;
71 IsPrecondSetup_[0] =
false;
74 ierr += InitializeDefaults();
75 TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error,
"Couldn't initialize default values.");
78 Teuchos::Array<int> GlobalRowIDs; GlobalRowIDs.resize(NumMyRows_);
80 for (
int i = MyRowStart_; i <= MyRowEnd_; i++) {
81 GlobalRowIDs[i-MyRowStart_] = i;
85 int new_value = 0;
int entries = 0;
86 std::set<int> Columns;
90 for(
int i = 0; i < NumMyRows_; i++){
91 ierr += HYPRE_ParCSRMatrixGetRow(ParMatrix_, i+MyRowStart_, &num_entries, &indices, &values);
92 ierr += HYPRE_ParCSRMatrixRestoreRow(ParMatrix_, i+MyRowStart_,&num_entries,&indices,&values);
93 TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error,
"Couldn't get row of matrix.");
94 entries = num_entries;
95 for(
int j = 0; j < num_entries; j++){
97 new_value = indices[j];
98 Columns.insert(new_value);
101 int NumMyCols = Columns.size();
102 Teuchos::Array<int> GlobalColIDs; GlobalColIDs.resize(NumMyCols);
104 std::set<int>::iterator it;
106 for (it = Columns.begin(); it != Columns.end(); it++) {
108 GlobalColIDs[counter] = *it;
109 counter = counter + 1;
113 Epetra_Map RowMap(-1, NumMyRows_, &GlobalRowIDs[0], 0, Comm());
114 Epetra_Map ColMap(-1, NumMyCols, &GlobalColIDs[0], 0, Comm());
117 SetMaps(RowMap, ColMap);
122 ierr += HYPRE_ParCSRMatrixGetComm(ParMatrix_, &comm);
123 TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error,
"Couldn't get communicator from Hypre Matrix.");
125 ierr += HYPRE_IJVectorCreate(comm, MyRowStart_, MyRowEnd_, &X_hypre);
126 ierr += HYPRE_IJVectorSetObjectType(X_hypre, HYPRE_PARCSR);
127 ierr += HYPRE_IJVectorInitialize(X_hypre);
128 ierr += HYPRE_IJVectorAssemble(X_hypre);
129 ierr += HYPRE_IJVectorGetObject(X_hypre, (
void**) &par_x);
130 TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error,
"Couldn't create Hypre X vector.");
132 ierr += HYPRE_IJVectorCreate(comm, MyRowStart_, MyRowEnd_, &Y_hypre);
133 ierr += HYPRE_IJVectorSetObjectType(Y_hypre, HYPRE_PARCSR);
134 ierr += HYPRE_IJVectorInitialize(Y_hypre);
135 ierr += HYPRE_IJVectorAssemble(Y_hypre);
136 ierr += HYPRE_IJVectorGetObject(Y_hypre, (
void**) &par_y);
137 TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error,
"Couldn't create Hypre Y vector.");
139 x_vec = (hypre_ParVector *) hypre_IJVectorObject(((hypre_IJVector *) X_hypre));
140 x_local = hypre_ParVectorLocalVector(x_vec);
142 y_vec = (hypre_ParVector *) hypre_IJVectorObject(((hypre_IJVector *) Y_hypre));
143 y_local = hypre_ParVectorLocalVector(y_vec);
146 SolverDestroyPtr_ = &HYPRE_ParCSRPCGDestroy;
147 SolverSetupPtr_ = &HYPRE_ParCSRPCGSetup;
148 SolverSolvePtr_ = &HYPRE_ParCSRPCGSolve;
149 SolverPrecondPtr_ = &HYPRE_ParCSRPCGSetPrecond;
153 PrecondDestroyPtr_ = &HYPRE_EuclidDestroy;
154 PrecondSetupPtr_ = &HYPRE_EuclidSetup;
155 PrecondSolvePtr_ = &HYPRE_EuclidSolve;
157 ComputeNumericConstants();
158 ComputeStructureConstants();
164 ierr += HYPRE_IJVectorDestroy(X_hypre);
165 TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error,
"Couldn't destroy the X Vector.");
166 ierr += HYPRE_IJVectorDestroy(Y_hypre);
167 TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error,
"Couldn't destroy the Y Vector.");
170 if(IsSolverSetup_[0] ==
true){
171 ierr += SolverDestroyPtr_(Solver_);
172 TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error,
"Couldn't destroy the Solver.");
174 if(IsPrecondSetup_[0] ==
true){
175 ierr += PrecondDestroyPtr_(Preconditioner_);
176 TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error,
"Couldn't destroy the Preconditioner.");
178 delete[] IsSolverSetup_;
179 delete[] IsPrecondSetup_;
184 double * Values,
int * Indices)
const
190 EPETRA_CHK_ERR(HYPRE_ParCSRMatrixGetRow(ParMatrix_, Row+RowMatrixRowMap().MinMyGID(), &num_entries, &indices, &values));
191 EPETRA_CHK_ERR(HYPRE_ParCSRMatrixRestoreRow(ParMatrix_, Row+RowMatrixRowMap().MinMyGID(), &num_entries, &indices, &values));
193 NumEntries = num_entries;
195 if(Length < NumEntries){
196 printf(
"The arrays passed in are not large enough. Allocate more space.\n");
200 for(
int i = 0; i < NumEntries; i++){
201 Values[i] = values[i];
202 Indices[i] = RowMatrixColMap().LID(indices[i]);
212 my_row[0] = Row+RowMatrixRowMap().MinMyGID();
214 EPETRA_CHK_ERR(HYPRE_IJMatrixGetRowCounts(Matrix_, 1, my_row, nentries));
215 NumEntries = nentries[0];
285 bool SameVectors =
false;
286 int NumVectors = X.NumVectors();
287 if (NumVectors != Y.NumVectors())
return -1;
288 if(X.Pointers() == Y.Pointers()){
291 for(
int VecNum = 0; VecNum < NumVectors; VecNum++) {
295 EPETRA_CHK_ERR((*X(VecNum)).ExtractView(&x_values));
296 double *x_temp = x_local->data;
297 double *y_temp = y_local->data;
299 EPETRA_CHK_ERR((*Y(VecNum)).ExtractView(&y_values));
301 y_values =
new double[X.MyLength()];
303 y_local->data = y_values;
304 EPETRA_CHK_ERR(HYPRE_ParVectorSetConstantValues(par_y,0.0));
307 x_local->data = x_values;
311 EPETRA_CHK_ERR(HYPRE_ParCSRMatrixMatvecT(1.0, ParMatrix_, par_x, 1.0, par_y));
313 EPETRA_CHK_ERR(HYPRE_ParCSRMatrixMatvec(1.0, ParMatrix_, par_x, 1.0, par_y));
316 int NumEntries = Y.MyLength();
317 std::vector<double> new_values; new_values.resize(NumEntries);
318 std::vector<int> new_indices; new_indices.resize(NumEntries);
319 for(
int i = 0; i < NumEntries; i++){
320 new_values[i] = y_values[i];
323 EPETRA_CHK_ERR((*Y(VecNum)).ReplaceMyValues(NumEntries, &new_values[0], &new_indices[0]));
326 x_local->data = x_temp;
327 y_local->data = y_temp;
329 double flops = (double) NumVectors * (
double) NumGlobalNonzeros();
337 EPETRA_CHK_ERR(pt2Func(Preconditioner_, parameter));
339 EPETRA_CHK_ERR(pt2Func(Solver_, parameter));
347 EPETRA_CHK_ERR(pt2Func(Preconditioner_, parameter));
349 EPETRA_CHK_ERR(pt2Func(Solver_, parameter));
357 EPETRA_CHK_ERR(pt2Func(Preconditioner_, parameter1, parameter2));
359 EPETRA_CHK_ERR(pt2Func(Solver_, parameter1, parameter2));
367 EPETRA_CHK_ERR(pt2Func(Preconditioner_, parameter1, parameter2));
369 EPETRA_CHK_ERR(pt2Func(Solver_, parameter1, parameter2));
377 EPETRA_CHK_ERR(pt2Func(Preconditioner_, parameter));
379 EPETRA_CHK_ERR(pt2Func(Solver_, parameter));
387 EPETRA_CHK_ERR(pt2Func(Preconditioner_, parameter));
389 EPETRA_CHK_ERR(pt2Func(Solver_, parameter));
402 if(IsSolverSetup_[0]){
403 SolverDestroyPtr_(Solver_);
404 IsSolverSetup_[0] =
false;
407 SolverDestroyPtr_ = &HYPRE_BoomerAMGDestroy;
408 SolverSetupPtr_ = &HYPRE_BoomerAMGSetup;
409 SolverPrecondPtr_ = NULL;
411 TransposeSolve_ =
true;
412 SolverSolvePtr_ = &HYPRE_BoomerAMGSolveT;
414 SolverSolvePtr_ = &HYPRE_BoomerAMGSolve;
418 if(IsSolverSetup_[0]){
419 SolverDestroyPtr_(Solver_);
420 IsSolverSetup_[0] =
false;
423 SolverDestroyPtr_ = &HYPRE_AMSDestroy;
424 SolverSetupPtr_ = &HYPRE_AMSSetup;
425 SolverSolvePtr_ = &HYPRE_AMSSolve;
426 SolverPrecondPtr_ = NULL;
429 if(IsSolverSetup_[0]){
430 SolverDestroyPtr_(Solver_);
431 IsSolverSetup_[0] =
false;
434 SolverDestroyPtr_ = &HYPRE_ParCSRHybridDestroy;
435 SolverSetupPtr_ = &HYPRE_ParCSRHybridSetup;
436 SolverSolvePtr_ = &HYPRE_ParCSRHybridSolve;
437 SolverPrecondPtr_ = &HYPRE_ParCSRHybridSetPrecond;
440 if(IsSolverSetup_[0]){
441 SolverDestroyPtr_(Solver_);
442 IsSolverSetup_[0] =
false;
445 SolverDestroyPtr_ = &HYPRE_ParCSRPCGDestroy;
446 SolverSetupPtr_ = &HYPRE_ParCSRPCGSetup;
447 SolverSolvePtr_ = &HYPRE_ParCSRPCGSolve;
448 SolverPrecondPtr_ = &HYPRE_ParCSRPCGSetPrecond;
451 if(IsSolverSetup_[0]){
452 SolverDestroyPtr_(Solver_);
453 IsSolverSetup_[0] =
false;
456 SolverDestroyPtr_ = &HYPRE_ParCSRGMRESDestroy;
457 SolverSetupPtr_ = &HYPRE_ParCSRGMRESSetup;
458 SolverSolvePtr_ = &HYPRE_ParCSRGMRESSolve;
459 SolverPrecondPtr_ = &HYPRE_ParCSRGMRESSetPrecond;
462 if(IsSolverSetup_[0]){
463 SolverDestroyPtr_(Solver_);
464 IsSolverSetup_[0] =
false;
467 SolverDestroyPtr_ = &HYPRE_ParCSRFlexGMRESDestroy;
468 SolverSetupPtr_ = &HYPRE_ParCSRFlexGMRESSetup;
469 SolverSolvePtr_ = &HYPRE_ParCSRFlexGMRESSolve;
470 SolverPrecondPtr_ = &HYPRE_ParCSRFlexGMRESSetPrecond;
473 if(IsSolverSetup_[0]){
474 SolverDestroyPtr_(Solver_);
475 IsSolverSetup_[0] =
false;
478 SolverDestroyPtr_ = &HYPRE_ParCSRLGMRESDestroy;
479 SolverSetupPtr_ = &HYPRE_ParCSRLGMRESSetup;
480 SolverSolvePtr_ = &HYPRE_ParCSRLGMRESSolve;
481 SolverPrecondPtr_ = &HYPRE_ParCSRLGMRESSetPrecond;
484 if(IsSolverSetup_[0]){
485 SolverDestroyPtr_(Solver_);
486 IsSolverSetup_[0] =
false;
489 SolverDestroyPtr_ = &HYPRE_ParCSRBiCGSTABDestroy;
490 SolverSetupPtr_ = &HYPRE_ParCSRBiCGSTABSetup;
491 SolverSolvePtr_ = &HYPRE_ParCSRBiCGSTABSolve;
492 SolverPrecondPtr_ = &HYPRE_ParCSRBiCGSTABSetPrecond;
502 if(IsPrecondSetup_[0]){
503 PrecondDestroyPtr_(Preconditioner_);
504 IsPrecondSetup_[0] =
false;
507 PrecondDestroyPtr_ = &HYPRE_BoomerAMGDestroy;
508 PrecondSetupPtr_ = &HYPRE_BoomerAMGSetup;
509 PrecondSolvePtr_ = &HYPRE_BoomerAMGSolve;
512 if(IsPrecondSetup_[0]){
513 PrecondDestroyPtr_(Preconditioner_);
514 IsPrecondSetup_[0] =
false;
517 PrecondDestroyPtr_ = &HYPRE_ParaSailsDestroy;
518 PrecondSetupPtr_ = &HYPRE_ParaSailsSetup;
519 PrecondSolvePtr_ = &HYPRE_ParaSailsSolve;
522 if(IsPrecondSetup_[0]){
523 PrecondDestroyPtr_(Preconditioner_);
524 IsPrecondSetup_[0] =
false;
527 PrecondDestroyPtr_ = &HYPRE_EuclidDestroy;
528 PrecondSetupPtr_ = &HYPRE_EuclidSetup;
529 PrecondSolvePtr_ = &HYPRE_EuclidSolve;
532 if(IsPrecondSetup_[0]){
533 PrecondDestroyPtr_(Preconditioner_);
534 IsPrecondSetup_[0] =
false;
537 PrecondDestroyPtr_ = &HYPRE_AMSDestroy;
538 PrecondSetupPtr_ = &HYPRE_AMSSetup;
539 PrecondSolvePtr_ = &HYPRE_AMSSolve;
553 HYPRE_ParCSRMatrixGetComm(ParMatrix_, &comm);
554 return (this->*SolverCreatePtr_)(comm, &Solver_);
560 HYPRE_ParCSRMatrixGetComm(ParMatrix_, &comm);
561 return (this->*PrecondCreatePtr_)(comm, &Preconditioner_);
566 if(UsePreconditioner ==
false){
569 if(SolverPrecondPtr_ == NULL){
572 SolverPrecondPtr_(Solver_, PrecondSolvePtr_, PrecondSetupPtr_, Preconditioner_);
580 SolveOrPrec_ = answer;
586 SolverSetupPtr_(Solver_, ParMatrix_, par_x, par_y);
587 IsSolverSetup_[0] =
true;
593 PrecondSetupPtr_(Preconditioner_, ParMatrix_, par_x, par_y);
594 IsPrecondSetup_[0] =
true;
600 bool SameVectors =
false;
601 int NumVectors = X.NumVectors();
602 if (NumVectors != Y.NumVectors())
return -1;
603 if(X.Pointers() == Y.Pointers()){
606 if(SolveOrPrec_ ==
Solver){
607 if(IsSolverSetup_[0] ==
false){
611 if(IsPrecondSetup_[0] ==
false){
615 for(
int VecNum = 0; VecNum < NumVectors; VecNum++) {
618 EPETRA_CHK_ERR((*X(VecNum)).ExtractView(&x_values));
621 EPETRA_CHK_ERR((*Y(VecNum)).ExtractView(&y_values));
623 y_values =
new double[X.MyLength()];
626 double *x_temp = x_local->data;
628 x_local->data = x_values;
629 double *y_temp = y_local->data;
630 y_local->data = y_values;
632 EPETRA_CHK_ERR(HYPRE_ParVectorSetConstantValues(par_y, 0.0));
633 if(transpose && !TransposeSolve_){
637 if(SolveOrPrec_ ==
Solver){
639 EPETRA_CHK_ERR(SolverSolvePtr_(Solver_, ParMatrix_, par_x, par_y));
642 EPETRA_CHK_ERR(PrecondSolvePtr_(Preconditioner_, ParMatrix_, par_x, par_y));
645 int NumEntries = Y.MyLength();
646 std::vector<double> new_values; new_values.resize(NumEntries);
647 std::vector<int> new_indices; new_indices.resize(NumEntries);
648 for(
int i = 0; i < NumEntries; i++){
649 new_values[i] = y_values[i];
652 EPETRA_CHK_ERR((*Y(VecNum)).ReplaceMyValues(NumEntries, &new_values[0], &new_indices[0]));
655 x_local->data = x_temp;
656 y_local->data = y_temp;
658 double flops = (double) NumVectors * (
double) NumGlobalNonzeros();
665 for(
int i = 0; i < NumMyRows_; i++){
670 EPETRA_CHK_ERR(HYPRE_ParCSRMatrixGetRow(ParMatrix_,i+MyRowStart_, &num_entries, &indices, &values));
671 EPETRA_CHK_ERR(HYPRE_ParCSRMatrixRestoreRow(ParMatrix_,i+MyRowStart_, &num_entries, &indices, &values));
672 Teuchos::Array<double> new_values; new_values.resize(num_entries);
673 Teuchos::Array<int> new_indices; new_indices.resize(num_entries);
674 for(
int j = 0; j < num_entries; j++){
676 new_values[j] = X[i]*values[j];
677 new_indices[j] = indices[j];
680 rows[0] = i+MyRowStart_;
681 EPETRA_CHK_ERR(HYPRE_IJMatrixSetValues(Matrix_, 1, &num_entries, rows, &new_indices[0], &new_values[0]));
684 HaveNumericConstants_ =
false;
685 UpdateFlops(NumGlobalNonzeros());
692 Epetra_Import Importer(RowMatrixColMap(), RowMatrixRowMap());
694 EPETRA_CHK_ERR(Import_Vector.Import(X, Importer, Insert, 0));
696 for(
int i = 0; i < NumMyRows_; i++){
702 EPETRA_CHK_ERR(HYPRE_ParCSRMatrixGetRow(ParMatrix_,i+MyRowStart_, &num_entries, &indices, &values));
703 EPETRA_CHK_ERR(HYPRE_ParCSRMatrixRestoreRow(ParMatrix_,i+MyRowStart_,&num_entries,&indices,&values));
704 Teuchos::Array<int> new_indices; new_indices.resize(num_entries);
705 Teuchos::Array<double> new_values; new_values.resize(num_entries);
706 for(
int j = 0; j < num_entries; j++){
708 int index = RowMatrixColMap().LID(indices[j]);
709 TEUCHOS_TEST_FOR_EXCEPTION(index < 0, std::logic_error,
"Index is negtive.");
710 new_values[j] = values[j] * Import_Vector[index];
711 new_indices[j] = indices[j];
715 rows[0] = i+MyRowStart_;
716 EPETRA_CHK_ERR(HYPRE_IJMatrixSetValues(Matrix_, 1, &num_entries, rows, &new_indices[0], &new_values[0]));
719 HaveNumericConstants_ =
false;
720 UpdateFlops(NumGlobalNonzeros());
728 EPETRA_CHK_ERR(HYPRE_IJMatrixGetObjectType(Matrix_, &my_type));
731 TEUCHOS_TEST_FOR_EXCEPTION(MatType_ != HYPRE_PARCSR, std::logic_error,
"Object is not type PARCSR");
734 EPETRA_CHK_ERR(HYPRE_IJMatrixGetObject(Matrix_, (
void**) &ParMatrix_));
736 int numRows, numCols;
739 EPETRA_CHK_ERR(HYPRE_ParCSRMatrixGetDims(ParMatrix_, &numRows, &numCols));
741 NumGlobalRows_ = numRows;
742 NumGlobalCols_ = numCols;
745 int ColStart, ColEnd;
746 EPETRA_CHK_ERR(HYPRE_ParCSRMatrixGetLocalRange(ParMatrix_, &MyRowStart_, &MyRowEnd_, &ColStart, &ColEnd));
749 NumMyRows_ = MyRowEnd_ - MyRowStart_+1;
int ExtractMyEntryView(int CurEntry, double *&Value, int &RowIndex, int &ColIndex)
Returns a reference to the ith entry in the matrix, along with its row and column index...
int Hypre_ParCSRLGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
LGMRES Create passing function.
virtual ~EpetraExt_HypreIJMatrix()
EpetraExt_HypreIJMatrix Destructor.
int LeftScale(const Epetra_Vector &X)
Scales the EpetraExt_HypreIJMatrix on the left with a Epetra_Vector x.
int InitializeDefaults()
Set global variables to default values.
int Solve(bool Upper, bool Trans, bool UnitDiagonal, const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Returns the result of a EpetraExt_HypreIJMatrix solving a Epetra_MultiVector X in Y...
int Multiply(bool TransA, const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Returns the result of a EpetraExt_HypreIJMatrix multiplied by a Epetra_MultiVector X in Y...
int Hypre_ParCSRPCGCreate(MPI_Comm comm, HYPRE_Solver *solver)
PCG Create passing function.
EpetraExt_HypreIJMatrix(HYPRE_IJMatrix matrix)
Epetra_HypreIJMatrix constructor.
int NumMyRowEntries(int MyRow, int &NumEntries) const
Return the current number of values stored for the specified local row.
Hypre_Chooser
Enumerated type to choose to solve or precondition.
int Hypre_ParCSRGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
GMRES Create passing function.
int RightScale(const Epetra_Vector &X)
Scales the EpetraExt_HypreIJMatrix on the right with a Epetra_Vector x.
int Hypre_ParCSRFlexGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
FlexGMRES Create passing function.
int CreatePrecond()
Create the preconditioner with selected type.
int Hypre_ParaSailsCreate(MPI_Comm comm, HYPRE_Solver *solver)
ParaSails Create passing function.
int Hypre_AMSCreate(MPI_Comm comm, HYPRE_Solver *solver)
AMS Create passing function.
int Hypre_BoomerAMGCreate(MPI_Comm comm, HYPRE_Solver *solver)
AMG Create passing function.
Hypre_Solver
Enumerated type for Hypre solvers.
int Hypre_EuclidCreate(MPI_Comm comm, HYPRE_Solver *solver)
Euclid Create passing function.
int Hypre_ParCSRHybridCreate(MPI_Comm comm, HYPRE_Solver *solver)
Hybrid Create passing function.
int ExtractMyRowCopy(int MyRow, int Length, int &NumEntries, double *Values, int *Indices) const
Returns a copy of the specified local row in user-provided arrays.
int SetParameter(Hypre_Chooser chooser, int(*pt2Func)(HYPRE_Solver, int), int parameter)
Set a parameter that takes a single int.
int Hypre_ParCSRBiCGSTABCreate(MPI_Comm comm, HYPRE_Solver *solver)
BiCGSTAB Create passing function.
int CreateSolver()
Create the solver with selected type.