|
IFPACK Development
|
00001 /*@HEADER 00002 // *********************************************************************** 00003 // 00004 // Ifpack: Object-Oriented Algebraic Preconditioner Package 00005 // Copyright (2009) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 //@HEADER 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 // Need to check if the RowMap is the way Hypre expects (if not more difficult) 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 // Next create vectors that will be used when ApplyInverse() is called 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 } //Constructor 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 } //Destroy() 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 } //Initialize() 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 } //SetParameters() 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 } //AddFunToList() 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 } //SetParameter() - int function pointer 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 } //SetParameter() - double function pointer 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 } //SetParameter() - double,int function pointer 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 } //SetParameter() int,int function pointer 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 } //SetParameter() - double* function pointer 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 } //SetParameter() - int* function pointer 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 } //SetParameter() - set type of solver 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 } //Compute() 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 } //CallFunctions() 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); // X and Y must have same number of vectors 00289 if(X.Pointers() == Y.Pointers()){ 00290 SameVectors = true; 00291 } 00292 for(int VecNum = 0; VecNum < NumVectors; VecNum++) { 00293 //Get values for current vector in multivector. 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 // Temporarily make a pointer to data in Hypre for end 00303 double *XTemp = XLocal_->data; 00304 // Replace data in Hypre vectors with epetra values 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 // Use the solver methods 00312 IFPACK_CHK_ERR(SolverSolvePtr_(Solver_, ParMatrix_, ParX_, ParY_)); 00313 } else { 00314 // Apply the preconditioner 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 } //ApplyInverse() 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); // X and Y must have same number of vectors 00344 if(X.Pointers() == Y.Pointers()){ 00345 SameVectors = true; 00346 } 00347 for(int VecNum = 0; VecNum < NumVectors; VecNum++) { 00348 //Get values for current vector in multivector. 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 // Temporarily make a pointer to data in Hypre for end 00362 // Replace data in Hypre vectors with epetra values 00363 XLocal_->data = XValues; 00364 // Do actual computation. 00365 if(TransA) { 00366 // Use transpose of A in multiply 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 } //Multiply() 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 } //Print() 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()) // cannot compute right now 00430 return(-1.0); 00431 Condest_ = Ifpack_Condest(*this, CT, MaxIters, Tol, Matrix_in); 00432 return(Condest_); 00433 } //Condest() 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 } //SetSolverType() 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 } //SetPrecondType() 00582 00583 //============================================================================== 00584 int Ifpack_Hypre::CreateSolver(){ 00585 MPI_Comm comm; 00586 HYPRE_ParCSRMatrixGetComm(ParMatrix_, &comm); 00587 return (this->*SolverCreatePtr_)(comm, &Solver_); 00588 } //CreateSolver() 00589 00590 //============================================================================== 00591 int Ifpack_Hypre::CreatePrecond(){ 00592 MPI_Comm comm; 00593 HYPRE_ParCSRMatrixGetComm(ParMatrix_, &comm); 00594 return (this->*PrecondCreatePtr_)(comm, &Preconditioner_); 00595 } //CreatePrecond() 00596 00597 #endif // HAVE_HYPRE && HAVE_MPI
1.7.4