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