00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "Ifpack_Hypre.h"
00030 #if defined(HAVE_HYPRE) && defined(HAVE_MPI)
00031
00032 #include "Ifpack_Utils.h"
00033 #include "Epetra_MpiComm.h"
00034 #include "Epetra_IntVector.h"
00035 #include "Epetra_Import.h"
00036 #include "Teuchos_ParameterList.hpp"
00037 #include "Teuchos_RCP.hpp"
00038
00039 using Teuchos::RCP;
00040 using Teuchos::rcp;
00041
00042 Ifpack_Hypre::Ifpack_Hypre(Epetra_RowMatrix* A):
00043 A_(rcp(A,false)),
00044 UseTranspose_(false),
00045 IsInitialized_(false),
00046 IsComputed_(false),
00047 Label_(),
00048 NumInitialize_(0),
00049 NumCompute_(0),
00050 NumApplyInverse_(0),
00051 InitializeTime_(0.0),
00052 ComputeTime_(0.0),
00053 ApplyInverseTime_(0.0),
00054 ComputeFlops_(0.0),
00055 ApplyInverseFlops_(0.0),
00056 Time_(A_->Comm()),
00057 SolveOrPrec_(Solver),
00058 NumFunsToCall_(0),
00059 SolverType_(PCG),
00060 PrecondType_(Euclid),
00061 UsePreconditioner_(false),
00062 NiceRowMap_(true)
00063 {
00064 IsSolverSetup_ = new bool[1];
00065 IsPrecondSetup_ = new bool[1];
00066 IsSolverSetup_[0] = false;
00067 IsPrecondSetup_[0] = false;
00068 MPI_Comm comm = GetMpiComm();
00069 int ilower = A_->RowMatrixRowMap().MinMyGID();
00070 int iupper = A_->RowMatrixRowMap().MaxMyGID();
00071
00072 std::vector<int> ilowers; ilowers.resize(Comm().NumProc());
00073 std::vector<int> iuppers; iuppers.resize(Comm().NumProc());
00074 int myLower[1]; myLower[0] = ilower;
00075 int myUpper[1]; myUpper[0] = iupper;
00076 Comm().GatherAll(myLower, &ilowers[0], 1);
00077 Comm().GatherAll(myUpper, &iuppers[0], 1);
00078 for(int i = 0; i < Comm().NumProc()-1; i++){
00079 NiceRowMap_ = (NiceRowMap_ && iuppers[i]+1 == ilowers[i+1]);
00080 }
00081 if(!NiceRowMap_){
00082 ilower = (A_->NumGlobalRows() / Comm().NumProc())*Comm().MyPID();
00083 iupper = (A_->NumGlobalRows() / Comm().NumProc())*(Comm().MyPID()+1)-1;
00084 if(Comm().MyPID() == Comm().NumProc()-1){
00085 iupper = A_-> NumGlobalRows()-1;
00086 }
00087 }
00088
00089
00090 IFPACK_CHK_ERRV(HYPRE_IJVectorCreate(comm, ilower, iupper, &XHypre_));
00091 IFPACK_CHK_ERRV(HYPRE_IJVectorSetObjectType(XHypre_, HYPRE_PARCSR));
00092 IFPACK_CHK_ERRV(HYPRE_IJVectorInitialize(XHypre_));
00093 IFPACK_CHK_ERRV(HYPRE_IJVectorAssemble(XHypre_));
00094 IFPACK_CHK_ERRV(HYPRE_IJVectorGetObject(XHypre_, (void**) &ParX_));
00095
00096 IFPACK_CHK_ERRV(HYPRE_IJVectorCreate(comm, ilower, iupper, &YHypre_));
00097 IFPACK_CHK_ERRV(HYPRE_IJVectorSetObjectType(YHypre_, HYPRE_PARCSR));
00098 IFPACK_CHK_ERRV(HYPRE_IJVectorInitialize(YHypre_));
00099 IFPACK_CHK_ERRV(HYPRE_IJVectorAssemble(YHypre_));
00100 IFPACK_CHK_ERRV(HYPRE_IJVectorGetObject(YHypre_, (void**) &ParY_));
00101
00102 XVec_ = (hypre_ParVector *) hypre_IJVectorObject(((hypre_IJVector *) XHypre_));
00103 XLocal_ = hypre_ParVectorLocalVector(XVec_);
00104
00105 YVec_ = (hypre_ParVector *) hypre_IJVectorObject(((hypre_IJVector *) YHypre_));
00106 YLocal_ = hypre_ParVectorLocalVector(YVec_);
00107 std::vector<int> rows; rows.resize(iupper - ilower +1);
00108 for(int i = ilower; i <= iupper; i++){
00109 rows[i-ilower] = i;
00110 }
00111 MySimpleMap_ = rcp(new Epetra_Map(-1, iupper-ilower+1, &rows[0], 0, Comm()));
00112 }
00113
00114
00115 void Ifpack_Hypre::Destroy(){
00116 if(IsInitialized()){
00117 IFPACK_CHK_ERRV(HYPRE_IJMatrixDestroy(HypreA_));
00118 }
00119 IFPACK_CHK_ERRV(HYPRE_IJVectorDestroy(XHypre_));
00120 IFPACK_CHK_ERRV(HYPRE_IJVectorDestroy(YHypre_));
00121 if(IsSolverSetup_[0]){
00122 IFPACK_CHK_ERRV(SolverDestroyPtr_(Solver_));
00123 }
00124 if(IsPrecondSetup_[0]){
00125 IFPACK_CHK_ERRV(PrecondDestroyPtr_(Preconditioner_));
00126 }
00127 delete[] IsSolverSetup_;
00128 delete[] IsPrecondSetup_;
00129 }
00130
00131
00132 int Ifpack_Hypre::Initialize(){
00133 Time_.ResetStartTime();
00134 MPI_Comm comm = GetMpiComm();
00135 int ilower = MySimpleMap_->MinMyGID();
00136 int iupper = MySimpleMap_->MaxMyGID();
00137 IFPACK_CHK_ERR(HYPRE_IJMatrixCreate(comm, ilower, iupper, ilower, iupper, &HypreA_));
00138 IFPACK_CHK_ERR(HYPRE_IJMatrixSetObjectType(HypreA_, HYPRE_PARCSR));
00139 IFPACK_CHK_ERR(HYPRE_IJMatrixInitialize(HypreA_));
00140 for(int i = 0; i < A_->NumMyRows(); i++){
00141 int numElements;
00142 IFPACK_CHK_ERR(A_->NumMyRowEntries(i,numElements));
00143 std::vector<int> indices; indices.resize(numElements);
00144 std::vector<double> values; values.resize(numElements);
00145 int numEntries;
00146 IFPACK_CHK_ERR(A_->ExtractMyRowCopy(i, numElements, numEntries, &values[0], &indices[0]));
00147 for(int j = 0; j < numEntries; j++){
00148 indices[j] = A_->RowMatrixColMap().GID(indices[j]);
00149 }
00150 int GlobalRow[1];
00151 GlobalRow[0] = A_->RowMatrixRowMap().GID(i);
00152 IFPACK_CHK_ERR(HYPRE_IJMatrixSetValues(HypreA_, 1, &numEntries, GlobalRow, &indices[0], &values[0]));
00153 }
00154 IFPACK_CHK_ERR(HYPRE_IJMatrixAssemble(HypreA_));
00155 IFPACK_CHK_ERR(HYPRE_IJMatrixGetObject(HypreA_, (void**)&ParMatrix_));
00156 IsInitialized_=true;
00157 NumInitialize_ = NumInitialize_ + 1;
00158 InitializeTime_ = InitializeTime_ + Time_.ElapsedTime();
00159 return 0;
00160 }
00161
00162
00163 int Ifpack_Hypre::SetParameters(Teuchos::ParameterList& list){
00164 List_ = list;
00165 Hypre_Solver solType = list.get("Solver", PCG);
00166 SolverType_ = solType;
00167 Hypre_Solver precType = list.get("Preconditioner", Euclid);
00168 PrecondType_ = precType;
00169 Hypre_Chooser chooser = list.get("SolveOrPrecondition", Solver);
00170 SolveOrPrec_ = chooser;
00171 bool SetPrecond = list.get("SetPreconditioner", false);
00172 IFPACK_CHK_ERR(SetParameter(SetPrecond));
00173 int NumFunctions = list.get("NumFunctions", 0);
00174 FunsToCall_.clear();
00175 NumFunsToCall_ = 0;
00176 if(NumFunctions > 0){
00177 RCP<FunctionParameter>* params = list.get<RCP<FunctionParameter>*>("Functions");
00178 for(int i = 0; i < NumFunctions; i++){
00179 IFPACK_CHK_ERR(AddFunToList(params[i]));
00180 }
00181 }
00182 return 0;
00183 }
00184
00185
00186 int Ifpack_Hypre::AddFunToList(RCP<FunctionParameter> NewFun){
00187 NumFunsToCall_ = NumFunsToCall_+1;
00188 FunsToCall_.resize(NumFunsToCall_);
00189 FunsToCall_[NumFunsToCall_-1] = NewFun;
00190 return 0;
00191 }
00192
00193
00194 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int), int parameter){
00195 RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter));
00196 IFPACK_CHK_ERR(AddFunToList(temp));
00197 return 0;
00198 }
00199
00200
00201 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double), double parameter){
00202 RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter));
00203 IFPACK_CHK_ERR(AddFunToList(temp));
00204 return 0;
00205 }
00206
00207
00208 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double, int), double parameter1, int parameter2){
00209 RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter1, parameter2));
00210 IFPACK_CHK_ERR(AddFunToList(temp));
00211 return 0;
00212 }
00213
00214
00215 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int, int), int parameter1, int parameter2){
00216 RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter1, parameter2));
00217 IFPACK_CHK_ERR(AddFunToList(temp));
00218 return 0;
00219 }
00220
00221
00222 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double*), double* parameter){
00223 RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter));
00224 IFPACK_CHK_ERR(AddFunToList(temp));
00225 return 0;
00226 }
00227
00228
00229 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int*), int* parameter){
00230 RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter));
00231 IFPACK_CHK_ERR(AddFunToList(temp));
00232 return 0;
00233 }
00234
00235
00236 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, Hypre_Solver solver){
00237 if(chooser == Solver){
00238 SolverType_ = solver;
00239 } else {
00240 PrecondType_ = solver;
00241 }
00242 return 0;
00243 }
00244
00245
00246 int Ifpack_Hypre::Compute(){
00247 if(IsInitialized() == false){
00248 IFPACK_CHK_ERR(Initialize());
00249 }
00250 Time_.ResetStartTime();
00251 IFPACK_CHK_ERR(SetSolverType(SolverType_));
00252 IFPACK_CHK_ERR(SetPrecondType(PrecondType_));
00253 CallFunctions();
00254 if(UsePreconditioner_){
00255 if(SolverPrecondPtr_ != NULL){
00256 IFPACK_CHK_ERR(SolverPrecondPtr_(Solver_, PrecondSolvePtr_, PrecondSetupPtr_, Preconditioner_));
00257 }
00258 }
00259 if(SolveOrPrec_ == Solver){
00260 IFPACK_CHK_ERR(SolverSetupPtr_(Solver_, ParMatrix_, ParX_, ParY_));
00261 IsSolverSetup_[0] = true;
00262 } else {
00263 IFPACK_CHK_ERR(PrecondSetupPtr_(Preconditioner_, ParMatrix_, ParX_, ParY_));
00264 IsPrecondSetup_[0] = true;
00265 }
00266 IsComputed_ = true;
00267 NumCompute_ = NumCompute_ + 1;
00268 ComputeTime_ = ComputeTime_ + Time_.ElapsedTime();
00269 return 0;
00270 }
00271
00272
00273 int Ifpack_Hypre::CallFunctions() const{
00274 for(int i = 0; i < NumFunsToCall_; i++){
00275 IFPACK_CHK_ERR(FunsToCall_[i]->CallFunction(Solver_, Preconditioner_));
00276 }
00277 return 0;
00278 }
00279
00280
00281 int Ifpack_Hypre::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const{
00282 if(IsComputed() == false){
00283 IFPACK_CHK_ERR(-1);
00284 }
00285 Time_.ResetStartTime();
00286 bool SameVectors = false;
00287 int NumVectors = X.NumVectors();
00288 if (NumVectors != Y.NumVectors()) IFPACK_CHK_ERR(-1);
00289 if(X.Pointers() == Y.Pointers()){
00290 SameVectors = true;
00291 }
00292 for(int VecNum = 0; VecNum < NumVectors; VecNum++) {
00293
00294 double * XValues;
00295 IFPACK_CHK_ERR((*X(VecNum)).ExtractView(&XValues));
00296 double * YValues;
00297 if(!SameVectors){
00298 IFPACK_CHK_ERR((*Y(VecNum)).ExtractView(&YValues));
00299 } else {
00300 YValues = new double[X.MyLength()];
00301 }
00302
00303 double *XTemp = XLocal_->data;
00304
00305 XLocal_->data = XValues;
00306 double *YTemp = YLocal_->data;
00307 YLocal_->data = YValues;
00308
00309 IFPACK_CHK_ERR(HYPRE_ParVectorSetConstantValues(ParY_, 0.0));
00310 if(SolveOrPrec_ == Solver){
00311
00312 IFPACK_CHK_ERR(SolverSolvePtr_(Solver_, ParMatrix_, ParX_, ParY_));
00313 } else {
00314
00315 IFPACK_CHK_ERR(PrecondSolvePtr_(Preconditioner_, ParMatrix_, ParX_, ParY_));
00316 }
00317 if(SameVectors){
00318 int NumEntries = Y.MyLength();
00319 std::vector<double> new_values; new_values.resize(NumEntries);
00320 std::vector<int> new_indices; new_indices.resize(NumEntries);
00321 for(int i = 0; i < NumEntries; i++){
00322 new_values[i] = YValues[i];
00323 new_indices[i] = i;
00324 }
00325 IFPACK_CHK_ERR((*Y(VecNum)).ReplaceMyValues(NumEntries, &new_values[0], &new_indices[0]));
00326 delete[] YValues;
00327 }
00328 XLocal_->data = XTemp;
00329 YLocal_->data = YTemp;
00330 }
00331 NumApplyInverse_ = NumApplyInverse_ + 1;
00332 ApplyInverseTime_ = ApplyInverseTime_ + Time_.ElapsedTime();
00333 return 0;
00334 }
00335
00336
00337 int Ifpack_Hypre::Multiply(bool TransA, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const{
00338 if(IsInitialized() == false){
00339 IFPACK_CHK_ERR(-1);
00340 }
00341 bool SameVectors = false;
00342 int NumVectors = X.NumVectors();
00343 if (NumVectors != Y.NumVectors()) IFPACK_CHK_ERR(-1);
00344 if(X.Pointers() == Y.Pointers()){
00345 SameVectors = true;
00346 }
00347 for(int VecNum = 0; VecNum < NumVectors; VecNum++) {
00348
00349 double * XValues;
00350 double * YValues;
00351 IFPACK_CHK_ERR((*X(VecNum)).ExtractView(&XValues));
00352 double *XTemp = XLocal_->data;
00353 double *YTemp = YLocal_->data;
00354 if(!SameVectors){
00355 IFPACK_CHK_ERR((*Y(VecNum)).ExtractView(&YValues));
00356 } else {
00357 YValues = new double[X.MyLength()];
00358 }
00359 YLocal_->data = YValues;
00360 IFPACK_CHK_ERR(HYPRE_ParVectorSetConstantValues(ParY_,0.0));
00361
00362
00363 XLocal_->data = XValues;
00364
00365 if(TransA) {
00366
00367 IFPACK_CHK_ERR(HYPRE_ParCSRMatrixMatvecT(1.0, ParMatrix_, ParX_, 1.0, ParY_));
00368 } else {
00369 IFPACK_CHK_ERR(HYPRE_ParCSRMatrixMatvec(1.0, ParMatrix_, ParX_, 1.0, ParY_));
00370 }
00371 if(SameVectors){
00372 int NumEntries = Y.MyLength();
00373 std::vector<double> new_values; new_values.resize(NumEntries);
00374 std::vector<int> new_indices; new_indices.resize(NumEntries);
00375 for(int i = 0; i < NumEntries; i++){
00376 new_values[i] = YValues[i];
00377 new_indices[i] = i;
00378 }
00379 IFPACK_CHK_ERR((*Y(VecNum)).ReplaceMyValues(NumEntries, &new_values[0], &new_indices[0]));
00380 delete[] YValues;
00381 }
00382 XLocal_->data = XTemp;
00383 YLocal_->data = YTemp;
00384 }
00385 return 0;
00386 }
00387
00388
00389 ostream& Ifpack_Hypre::Print(ostream& os) const{
00390 if (!Comm().MyPID()) {
00391 os << endl;
00392 os << "================================================================================" << endl;
00393 os << "Ifpack_Hypre: " << Label () << endl << endl;
00394 os << "Using " << Comm().NumProc() << " processors." << endl;
00395 os << "Global number of rows = " << A_->NumGlobalRows() << endl;
00396 os << "Global number of nonzeros = " << A_->NumGlobalNonzeros() << endl;
00397 os << "Condition number estimate = " << Condest() << endl;
00398 os << endl;
00399 os << "Phase # calls Total Time (s) Total MFlops MFlops/s" << endl;
00400 os << "----- ------- -------------- ------------ --------" << endl;
00401 os << "Initialize() " << std::setw(5) << NumInitialize_
00402 << " " << std::setw(15) << InitializeTime_
00403 << " 0.0 0.0" << endl;
00404 os << "Compute() " << std::setw(5) << NumCompute_
00405 << " " << std::setw(15) << ComputeTime_
00406 << " " << std::setw(15) << 1.0e-6 * ComputeFlops_;
00407 if (ComputeTime_ != 0.0)
00408 os << " " << std::setw(15) << 1.0e-6 * ComputeFlops_ / ComputeTime_ << endl;
00409 else
00410 os << " " << std::setw(15) << 0.0 << endl;
00411 os << "ApplyInverse() " << std::setw(5) << NumApplyInverse_
00412 << " " << std::setw(15) << ApplyInverseTime_
00413 << " " << std::setw(15) << 1.0e-6 * ApplyInverseFlops_;
00414 if (ApplyInverseTime_ != 0.0)
00415 os << " " << std::setw(15) << 1.0e-6 * ApplyInverseFlops_ / ApplyInverseTime_ << endl;
00416 else
00417 os << " " << std::setw(15) << 0.0 << endl;
00418 os << "================================================================================" << endl;
00419 os << endl;
00420 }
00421 return os;
00422 }
00423
00424
00425 double Ifpack_Hypre::Condest(const Ifpack_CondestType CT,
00426 const int MaxIters,
00427 const double Tol,
00428 Epetra_RowMatrix* Matrix_in){
00429 if (!IsComputed())
00430 return(-1.0);
00431 Condest_ = Ifpack_Condest(*this, CT, MaxIters, Tol, Matrix_in);
00432 return(Condest_);
00433 }
00434
00435
00436 int Ifpack_Hypre::SetSolverType(Hypre_Solver Solver){
00437 switch(Solver) {
00438 case BoomerAMG:
00439 if(IsSolverSetup_[0]){
00440 SolverDestroyPtr_(Solver_);
00441 IsSolverSetup_[0] = false;
00442 }
00443 SolverCreatePtr_ = &Ifpack_Hypre::Hypre_BoomerAMGCreate;
00444 SolverDestroyPtr_ = &HYPRE_BoomerAMGDestroy;
00445 SolverSetupPtr_ = &HYPRE_BoomerAMGSetup;
00446 SolverPrecondPtr_ = NULL;
00447 SolverSolvePtr_ = &HYPRE_BoomerAMGSolve;
00448 break;
00449 case AMS:
00450 if(IsSolverSetup_[0]){
00451 SolverDestroyPtr_(Solver_);
00452 IsSolverSetup_[0] = false;
00453 }
00454 SolverCreatePtr_ = &Ifpack_Hypre::Hypre_AMSCreate;
00455 SolverDestroyPtr_ = &HYPRE_AMSDestroy;
00456 SolverSetupPtr_ = &HYPRE_AMSSetup;
00457 SolverSolvePtr_ = &HYPRE_AMSSolve;
00458 SolverPrecondPtr_ = NULL;
00459 break;
00460 case Hybrid:
00461 if(IsSolverSetup_[0]){
00462 SolverDestroyPtr_(Solver_);
00463 IsSolverSetup_[0] = false;
00464 }
00465 SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRHybridCreate;
00466 SolverDestroyPtr_ = &HYPRE_ParCSRHybridDestroy;
00467 SolverSetupPtr_ = &HYPRE_ParCSRHybridSetup;
00468 SolverSolvePtr_ = &HYPRE_ParCSRHybridSolve;
00469 SolverPrecondPtr_ = &HYPRE_ParCSRHybridSetPrecond;
00470 break;
00471 case PCG:
00472 if(IsSolverSetup_[0]){
00473 SolverDestroyPtr_(Solver_);
00474 IsSolverSetup_[0] = false;
00475 }
00476 SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRPCGCreate;
00477 SolverDestroyPtr_ = &HYPRE_ParCSRPCGDestroy;
00478 SolverSetupPtr_ = &HYPRE_ParCSRPCGSetup;
00479 SolverSolvePtr_ = &HYPRE_ParCSRPCGSolve;
00480 SolverPrecondPtr_ = &HYPRE_ParCSRPCGSetPrecond;
00481 break;
00482 case GMRES:
00483 if(IsSolverSetup_[0]){
00484 SolverDestroyPtr_(Solver_);
00485 IsSolverSetup_[0] = false;
00486 }
00487 SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRGMRESCreate;
00488 SolverDestroyPtr_ = &HYPRE_ParCSRGMRESDestroy;
00489 SolverSetupPtr_ = &HYPRE_ParCSRGMRESSetup;
00490 SolverPrecondPtr_ = &HYPRE_ParCSRGMRESSetPrecond;
00491 break;
00492 case FlexGMRES:
00493 if(IsSolverSetup_[0]){
00494 SolverDestroyPtr_(Solver_);
00495 IsSolverSetup_[0] = false;
00496 }
00497 SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRFlexGMRESCreate;
00498 SolverDestroyPtr_ = &HYPRE_ParCSRFlexGMRESDestroy;
00499 SolverSetupPtr_ = &HYPRE_ParCSRFlexGMRESSetup;
00500 SolverSolvePtr_ = &HYPRE_ParCSRFlexGMRESSolve;
00501 SolverPrecondPtr_ = &HYPRE_ParCSRFlexGMRESSetPrecond;
00502 break;
00503 case LGMRES:
00504 if(IsSolverSetup_[0]){
00505 SolverDestroyPtr_(Solver_);
00506 IsSolverSetup_[0] = false;
00507 }
00508 SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRLGMRESCreate;
00509 SolverDestroyPtr_ = &HYPRE_ParCSRLGMRESDestroy;
00510 SolverSetupPtr_ = &HYPRE_ParCSRLGMRESSetup;
00511 SolverSolvePtr_ = &HYPRE_ParCSRLGMRESSolve;
00512 SolverPrecondPtr_ = &HYPRE_ParCSRLGMRESSetPrecond;
00513 break;
00514 case BiCGSTAB:
00515 if(IsSolverSetup_[0]){
00516 SolverDestroyPtr_(Solver_);
00517 IsSolverSetup_[0] = false;
00518 }
00519 SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRBiCGSTABCreate;
00520 SolverDestroyPtr_ = &HYPRE_ParCSRBiCGSTABDestroy;
00521 SolverSetupPtr_ = &HYPRE_ParCSRBiCGSTABSetup;
00522 SolverSolvePtr_ = &HYPRE_ParCSRBiCGSTABSolve;
00523 SolverPrecondPtr_ = &HYPRE_ParCSRBiCGSTABSetPrecond;
00524 break;
00525 default:
00526 return -1;
00527 }
00528 CreateSolver();
00529 return 0;
00530 }
00531
00532
00533 int Ifpack_Hypre::SetPrecondType(Hypre_Solver Precond){
00534 switch(Precond) {
00535 case BoomerAMG:
00536 if(IsPrecondSetup_[0]){
00537 PrecondDestroyPtr_(Preconditioner_);
00538 IsPrecondSetup_[0] = false;
00539 }
00540 PrecondCreatePtr_ = &Ifpack_Hypre::Hypre_BoomerAMGCreate;
00541 PrecondDestroyPtr_ = &HYPRE_BoomerAMGDestroy;
00542 PrecondSetupPtr_ = &HYPRE_BoomerAMGSetup;
00543 PrecondSolvePtr_ = &HYPRE_BoomerAMGSolve;
00544 break;
00545 case ParaSails:
00546 if(IsPrecondSetup_[0]){
00547 PrecondDestroyPtr_(Preconditioner_);
00548 IsPrecondSetup_[0] = false;
00549 }
00550 PrecondCreatePtr_ = &Ifpack_Hypre::Hypre_ParaSailsCreate;
00551 PrecondDestroyPtr_ = &HYPRE_ParaSailsDestroy;
00552 PrecondSetupPtr_ = &HYPRE_ParaSailsSetup;
00553 PrecondSolvePtr_ = &HYPRE_ParaSailsSolve;
00554 break;
00555 case Euclid:
00556 if(IsPrecondSetup_[0]){
00557 PrecondDestroyPtr_(Preconditioner_);
00558 IsPrecondSetup_[0] = false;
00559 }
00560 PrecondCreatePtr_ = &Ifpack_Hypre::Hypre_EuclidCreate;
00561 PrecondDestroyPtr_ = &HYPRE_EuclidDestroy;
00562 PrecondSetupPtr_ = &HYPRE_EuclidSetup;
00563 PrecondSolvePtr_ = &HYPRE_EuclidSolve;
00564 break;
00565 case AMS:
00566 if(IsPrecondSetup_[0]){
00567 PrecondDestroyPtr_(Preconditioner_);
00568 IsPrecondSetup_[0] = false;
00569 }
00570 PrecondCreatePtr_ = &Ifpack_Hypre::Hypre_AMSCreate;
00571 PrecondDestroyPtr_ = &HYPRE_AMSDestroy;
00572 PrecondSetupPtr_ = &HYPRE_AMSSetup;
00573 PrecondSolvePtr_ = &HYPRE_AMSSolve;
00574 break;
00575 default:
00576 return -1;
00577 }
00578 CreatePrecond();
00579 return 0;
00580
00581 }
00582
00583
00584 int Ifpack_Hypre::CreateSolver(){
00585 MPI_Comm comm;
00586 HYPRE_ParCSRMatrixGetComm(ParMatrix_, &comm);
00587 return (this->*SolverCreatePtr_)(comm, &Solver_);
00588 }
00589
00590
00591 int Ifpack_Hypre::CreatePrecond(){
00592 MPI_Comm comm;
00593 HYPRE_ParCSRMatrixGetComm(ParMatrix_, &comm);
00594 return (this->*PrecondCreatePtr_)(comm, &Preconditioner_);
00595 }
00596
00597 #endif // HAVE_HYPRE && HAVE_MPI