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 #include "Ifpack_ConfigDefs.h"
00031 #include "Ifpack_Preconditioner.h"
00032 #include "Ifpack_Amesos.h"
00033 #include "Ifpack_Condest.h"
00034 #include "Epetra_MultiVector.h"
00035 #include "Epetra_Map.h"
00036 #include "Epetra_Comm.h"
00037 #include "Amesos.h"
00038 #include "Epetra_LinearProblem.h"
00039 #include "Epetra_RowMatrix.h"
00040 #include "Epetra_Time.h"
00041 #include "Teuchos_ParameterList.hpp"
00042
00043 static bool FirstTime = true;
00044
00045
00046 Ifpack_Amesos::Ifpack_Amesos(Epetra_RowMatrix* Matrix) :
00047 Matrix_(Teuchos::rcp( Matrix, false )),
00048 Label_("Amesos_Klu"),
00049 IsInitialized_(false),
00050 IsComputed_(false),
00051 UseTranspose_(false),
00052 NumInitialize_(0),
00053 NumCompute_(0),
00054 NumApplyInverse_(0),
00055 InitializeTime_(0.0),
00056 ComputeTime_(0.0),
00057 ApplyInverseTime_(0.0),
00058 ComputeFlops_(0),
00059 ApplyInverseFlops_(0),
00060 Condest_(-1.0)
00061 {
00062 Problem_ = Teuchos::rcp( new Epetra_LinearProblem );
00063 }
00064
00065
00066 Ifpack_Amesos::Ifpack_Amesos(const Ifpack_Amesos& rhs) :
00067 Matrix_(Teuchos::rcp( &rhs.Matrix(), false )),
00068 Label_(rhs.Label()),
00069 IsInitialized_(false),
00070 IsComputed_(false),
00071 NumInitialize_(rhs.NumInitialize()),
00072 NumCompute_(rhs.NumCompute()),
00073 NumApplyInverse_(rhs.NumApplyInverse()),
00074 InitializeTime_(rhs.InitializeTime()),
00075 ComputeTime_(rhs.ComputeTime()),
00076 ApplyInverseTime_(rhs.ApplyInverseTime()),
00077 ComputeFlops_(rhs.ComputeFlops()),
00078 ApplyInverseFlops_(rhs.ApplyInverseFlops()),
00079 Condest_(rhs.Condest())
00080 {
00081
00082 Problem_ = Teuchos::rcp( new Epetra_LinearProblem );
00083
00084
00085 Teuchos::ParameterList RHSList(rhs.List());
00086 List_ = RHSList;
00087
00088
00089
00090
00091 if (rhs.IsInitialized()) {
00092 IsInitialized_ = true;
00093 Initialize();
00094 }
00095 if (rhs.IsComputed()) {
00096 IsComputed_ = true;
00097 Compute();
00098 }
00099
00100 }
00101
00102 int Ifpack_Amesos::SetParameters(Teuchos::ParameterList& List)
00103 {
00104
00105 List_ = List;
00106 Label_ = List.get("amesos: solver type", Label_);
00107 return(0);
00108 }
00109
00110
00111 int Ifpack_Amesos::Initialize()
00112 {
00113
00114 IsInitialized_ = false;
00115 IsComputed_ = false;
00116
00117 if (Matrix_ == Teuchos::null)
00118 IFPACK_CHK_ERR(-1);
00119
00120 #if 0
00121
00122
00123 if (Comm().NumProc() != 1) {
00124 cout << "Class Ifpack_Amesos must be used for serial runs;" << endl;
00125 cout << "for parallel runs you should declare objects as:" << endl;
00126 cout << "Ifpack_AdditiveSchwarz<Ifpack_Amesos> APrec(Matrix)" << endl;
00127 exit(EXIT_FAILURE);
00128 }
00129 #endif
00130
00131
00132 if (Matrix_->NumGlobalRows() != Matrix_->NumGlobalCols())
00133 IFPACK_CHK_ERR(-1);
00134
00135
00136 if (Matrix_->NumMyNonzeros() == 0)
00137 IFPACK_CHK_ERR(-1);
00138
00139 Problem_->SetOperator(const_cast<Epetra_RowMatrix*>(Matrix_.get()));
00140
00141 if (Time_ == Teuchos::null)
00142 Time_ = Teuchos::rcp( new Epetra_Time(Comm()) );
00143
00144 Amesos Factory;
00145 Solver_ = Teuchos::rcp( Factory.Create((char*)Label_.c_str(),*Problem_) );
00146
00147 if (Solver_ == Teuchos::null)
00148 {
00149
00150 Solver_ = Teuchos::rcp( Factory.Create("Amesos_Klu",*Problem_) );
00151 }
00152 if (Solver_ == Teuchos::null)
00153 {
00154
00155
00156
00157 if (FirstTime)
00158 {
00159 cerr << "IFPACK WARNING: In class Ifpack_Amesos:" << endl;
00160 cerr << "IFPACK WARNING: Using LAPACK because other Amesos" << endl;
00161 cerr << "IFPACK WARNING: solvers are not available. LAPACK" << endl;
00162 cerr << "IFPACK WARNING: allocates memory to store the matrix as" << endl;
00163 cerr << "IFPACK WARNING: dense, I hope you have enough memory..." << endl;
00164 cerr << "IFPACK WARNING: (file " << __FILE__ << ", line " << __LINE__
00165 << ")" << endl;
00166 FirstTime = false;
00167 }
00168 Solver_ = Teuchos::rcp( Factory.Create("Amesos_Lapack",*Problem_) );
00169 }
00170
00171 if (Solver_ == Teuchos::null)
00172 IFPACK_CHK_ERR(-1);
00173
00174 IFPACK_CHK_ERR(Solver_->SetUseTranspose(UseTranspose_));
00175 Solver_->SetParameters(List_);
00176 IFPACK_CHK_ERR(Solver_->SymbolicFactorization());
00177
00178 IsInitialized_ = true;
00179 ++NumInitialize_;
00180 InitializeTime_ += Time_->ElapsedTime();
00181 return(0);
00182 }
00183
00184
00185 int Ifpack_Amesos::Compute()
00186 {
00187
00188 if (!IsInitialized())
00189 IFPACK_CHK_ERR(Initialize());
00190
00191 IsComputed_ = false;
00192 Time_->ResetStartTime();
00193
00194 if (Matrix_ == Teuchos::null)
00195 IFPACK_CHK_ERR(-1);
00196
00197 IFPACK_CHK_ERR(Solver_->NumericFactorization());
00198
00199 IsComputed_ = true;
00200 ++NumCompute_;
00201 ComputeTime_ += Time_->ElapsedTime();
00202 return(0);
00203 }
00204
00205
00206 int Ifpack_Amesos::SetUseTranspose(bool UseTranspose)
00207 {
00208
00209
00210 UseTranspose_ = UseTranspose;
00211 if (Solver_ != Teuchos::null)
00212 IFPACK_CHK_ERR(Solver_->SetUseTranspose(UseTranspose));
00213
00214 return(0);
00215 }
00216
00217
00218 int Ifpack_Amesos::
00219 Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
00220 {
00221
00222 IFPACK_CHK_ERR(Matrix_->Apply(X,Y));
00223 return(0);
00224 }
00225
00226
00227 int Ifpack_Amesos::
00228 ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
00229 {
00230
00231 if (IsComputed() == false)
00232 IFPACK_CHK_ERR(-1);
00233
00234 if (X.NumVectors() != Y.NumVectors())
00235 IFPACK_CHK_ERR(-1);
00236
00237 Time_->ResetStartTime();
00238
00239
00240
00241 Teuchos::RefCountPtr<const Epetra_MultiVector> Xcopy;
00242 if (X.Pointers()[0] == Y.Pointers()[0])
00243 Xcopy = Teuchos::rcp( new Epetra_MultiVector(X) );
00244 else
00245 Xcopy = Teuchos::rcp( &X, false );
00246
00247 Problem_->SetLHS(&Y);
00248 Problem_->SetRHS((Epetra_MultiVector*)Xcopy.get());
00249 IFPACK_CHK_ERR(Solver_->Solve());
00250
00251 ++NumApplyInverse_;
00252 ApplyInverseTime_ += Time_->ElapsedTime();
00253
00254 return(0);
00255 }
00256
00257
00258 double Ifpack_Amesos::NormInf() const
00259 {
00260 return(-1.0);
00261 }
00262
00263
00264 const char* Ifpack_Amesos::Label() const
00265 {
00266 return((char*)Label_.c_str());
00267 }
00268
00269
00270 bool Ifpack_Amesos::UseTranspose() const
00271 {
00272 return(UseTranspose_);
00273 }
00274
00275
00276 bool Ifpack_Amesos::HasNormInf() const
00277 {
00278 return(false);
00279 }
00280
00281
00282 const Epetra_Comm & Ifpack_Amesos::Comm() const
00283 {
00284 return(Matrix_->Comm());
00285 }
00286
00287
00288 const Epetra_Map & Ifpack_Amesos::OperatorDomainMap() const
00289 {
00290 return(Matrix_->OperatorDomainMap());
00291 }
00292
00293
00294 const Epetra_Map & Ifpack_Amesos::OperatorRangeMap() const
00295 {
00296 return(Matrix_->OperatorRangeMap());
00297 }
00298
00299
00300 double Ifpack_Amesos::Condest(const Ifpack_CondestType CT,
00301 const int MaxIters, const double Tol,
00302 Epetra_RowMatrix* Matrix)
00303 {
00304
00305 if (!IsComputed())
00306 return(-1.0);
00307
00308 if (Condest_ == -1.0)
00309 Condest_ = Ifpack_Condest(*this, CT, MaxIters, Tol, Matrix);
00310
00311 return(Condest_);
00312 }
00313
00314
00315 std::ostream& Ifpack_Amesos::Print(std::ostream& os) const
00316 {
00317 if (!Comm().MyPID()) {
00318 os << endl;
00319 os << "================================================================================" << endl;
00320 os << "Ifpack_Amesos: " << Label () << endl << endl;
00321 os << "Condition number estimate = " << Condest() << endl;
00322 os << "Global number of rows = " << Matrix_->NumGlobalRows() << endl;
00323 os << endl;
00324 os << "Phase # calls Total Time (s) Total MFlops MFlops/s" << endl;
00325 os << "----- ------- -------------- ------------ --------" << endl;
00326 os << "Initialize() " << std::setw(5) << NumInitialize_
00327 << " " << std::setw(15) << InitializeTime_
00328 << " 0.0 0.0" << endl;
00329 os << "Compute() " << std::setw(5) << NumCompute_
00330 << " " << std::setw(15) << ComputeTime_
00331 << " " << std::setw(15) << 1.0e-6 * ComputeFlops_;
00332 if (ComputeTime_ != 0.0)
00333 os << " " << std::setw(15) << 1.0e-6 * ComputeFlops_ / ComputeTime_ << endl;
00334 else
00335 os << " " << std::setw(15) << 0.0 << endl;
00336 os << "ApplyInverse() " << std::setw(5) << NumApplyInverse_
00337 << " " << std::setw(15) << ApplyInverseTime_
00338 << " " << std::setw(15) << 1.0e-6 * ApplyInverseFlops_;
00339 if (ApplyInverseTime_ != 0.0)
00340 os << " " << std::setw(15) << 1.0e-6 * ApplyInverseFlops_ / ApplyInverseTime_ << endl;
00341 else
00342 os << " " << std::setw(15) << 0.0 << endl;
00343 os << "================================================================================" << endl;
00344 os << endl;
00345 }
00346
00347 return(os);
00348 }