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_ConfigDefs.h"
00030 #include "Ifpack_SILU.h"
00031 #ifdef HAVE_IFPACK_SUPERLU
00032
00033 #include "Ifpack_CondestType.h"
00034 #include "Epetra_ConfigDefs.h"
00035 #include "Epetra_Comm.h"
00036 #include "Epetra_Map.h"
00037 #include "Epetra_RowMatrix.h"
00038 #include "Epetra_Vector.h"
00039 #include "Epetra_MultiVector.h"
00040 #include "Epetra_CrsGraph.h"
00041 #include "Epetra_CrsMatrix.h"
00042 #include "Teuchos_ParameterList.hpp"
00043 #include "Teuchos_RefCountPtr.hpp"
00044
00045
00046 extern "C" {int dfill_diag(int n, NCformat *Astore);}
00047
00048 using Teuchos::RefCountPtr;
00049 using Teuchos::rcp;
00050
00051 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
00052 # include "Teuchos_TimeMonitor.hpp"
00053 #endif
00054
00055
00056 Ifpack_SILU::Ifpack_SILU(Epetra_RowMatrix* Matrix_in) :
00057 A_(rcp(Matrix_in,false)),
00058 Comm_(Matrix_in->Comm()),
00059 UseTranspose_(false),
00060 NumMyDiagonals_(0),
00061 DropTol_(1e-4),
00062 FillTol_(1e-2),
00063 FillFactor_(10.0),
00064 DropRule_(9),
00065 Condest_(-1.0),
00066 IsInitialized_(false),
00067 IsComputed_(false),
00068 NumInitialize_(0),
00069 NumCompute_(0),
00070 NumApplyInverse_(0),
00071 InitializeTime_(0.0),
00072 ComputeTime_(0.0),
00073 ApplyInverseTime_(0.0),
00074 Time_(Comm()),
00075 etree_(0),
00076 perm_r_(0),
00077 perm_c_(0)
00078 {
00079 Teuchos::ParameterList List;
00080 SetParameters(List);
00081 SY_.Store=0;
00082 }
00083
00084
00085
00086
00087 void Ifpack_SILU::Destroy()
00088 {
00089 if(IsInitialized_){
00090
00091 StatFree(&stat_);
00092
00093 Destroy_CompCol_Permuted(&SAc_);
00094 Destroy_SuperNode_Matrix(&SL_);
00095 Destroy_CompCol_Matrix(&SU_);
00096
00097
00098 Destroy_SuperMatrix_Store(&SA_);
00099 if(SY_.Store) Destroy_SuperMatrix_Store(&SY_);
00100 SY_.Store=0;
00101
00102
00103 delete [] etree_;etree_=0;
00104 delete [] perm_r_;perm_r_=0;
00105 delete [] perm_c_;perm_c_=0;
00106 }
00107 }
00108
00109
00110 int Ifpack_SILU::SetParameters(Teuchos::ParameterList& List)
00111 {
00112 DropTol_=List.get("fact: drop tolerance",DropTol_);
00113 FillTol_=List.get("fact: zero pivot threshold",FillTol_);
00114 FillFactor_=List.get("fact: maximum fill factor",FillFactor_);
00115 DropRule_=List.get("fact: silu drop rule",DropRule_);
00116
00117
00118 sprintf(Label_, "IFPACK SILU (drop=%d, zpv=%f, ffact=%f, rthr=%f)",
00119 DropRule(),FillTol(),FillFactor(),DropTol());
00120 return(0);
00121 }
00122
00123
00124 int Ifpack_SILU::Initialize()
00125 {
00126
00127 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
00128 TEUCHOS_FUNC_TIME_MONITOR("Ifpack_SILU::Initialize");
00129 #endif
00130
00131 Time_.ResetStartTime();
00132
00133
00134 Destroy();
00135
00136 IsInitialized_ = false;
00137
00138 Epetra_CrsMatrix* CrsMatrix;
00139 CrsMatrix = dynamic_cast<Epetra_CrsMatrix*>(&*A_);
00140
00141 if(CrsMatrix && CrsMatrix->RowMap().SameAs(CrsMatrix->ColMap()) && CrsMatrix->IndicesAreContiguous()){
00142
00143 Aover_=rcp(CrsMatrix,false);
00144 }
00145 else if(CrsMatrix && CrsMatrix->IndicesAreContiguous()){
00146
00147 int size = A_->MaxNumEntries();
00148 int N=A_->NumMyRows();
00149 Aover_ = rcp(new Epetra_CrsMatrix(Copy,A_->RowMatrixRowMap(), size));
00150 vector<int> Indices(size);
00151 vector<double> Values(size);
00152
00153 int i,j,ct,*rowptr,*colind;
00154 double *values;
00155 IFPACK_CHK_ERR(CrsMatrix->ExtractCrsDataPointers(rowptr,colind,values));
00156
00157
00158 for(i=0;i<N;i++){
00159 for(j=rowptr[i],ct=0;j<rowptr[i+1];j++){
00160 if(colind[j]<N){
00161 Indices[ct]=CrsMatrix->GCID(colind[j]);
00162 Values[ct]=values[j];
00163 ct++;
00164 }
00165 }
00166 Aover_->InsertGlobalValues(CrsMatrix->GRID(i),ct,&Values[0],&Indices[0]);
00167 }
00168 IFPACK_CHK_ERR(Aover_->FillComplete(CrsMatrix->RowMap(),CrsMatrix->RowMap()));
00169 }
00170 else{
00171
00172 int size = A_->MaxNumEntries();
00173 Aover_ = rcp(new Epetra_CrsMatrix(Copy,A_->RowMatrixRowMap(), size));
00174 if (Aover_.get() == 0) IFPACK_CHK_ERR(-5);
00175
00176 vector<int> Indices1(size),Indices2(size);
00177 vector<double> Values1(size),Values2(size);
00178
00179
00180
00181 int N=A_->NumMyRows();
00182 for (int i = 0 ; i < N ; ++i) {
00183 int NumEntries;
00184 int GlobalRow = A_->RowMatrixRowMap().GID(i);
00185 IFPACK_CHK_ERR(A_->ExtractMyRowCopy(i, size, NumEntries,
00186 &Values1[0], &Indices1[0]));
00187
00188
00189 int ct=0;
00190 for (int j=0; j < NumEntries ; ++j) {
00191 if(Indices1[j] < N){
00192 Indices2[ct] = A_->RowMatrixColMap().GID(Indices1[j]);
00193 Values2[ct]=Values1[j];
00194 ct++;
00195 }
00196 }
00197 IFPACK_CHK_ERR(Aover_->InsertGlobalValues(GlobalRow,ct,
00198 &Values2[0],&Indices2[0]));
00199 }
00200 IFPACK_CHK_ERR(Aover_->FillComplete(A_->RowMatrixRowMap(),A_->RowMatrixRowMap()));
00201 }
00202
00203
00204 Aover_->OptimizeStorage();
00205 Graph_=rcp(const_cast<Epetra_CrsGraph*>(&Aover_->Graph()),false);
00206
00207 IsInitialized_ = true;
00208 NumInitialize_++;
00209 InitializeTime_ += Time_.ElapsedTime();
00210
00211 return(0);
00212 }
00213
00214
00215 int Ifpack_SILU::Compute()
00216 {
00217
00218 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
00219 TEUCHOS_FUNC_TIME_MONITOR("Ifpack_SILU::Compute");
00220 #endif
00221
00222 if (!IsInitialized())
00223 IFPACK_CHK_ERR(Initialize());
00224
00225 Time_.ResetStartTime();
00226 IsComputed_ = false;
00227
00228
00229 StatInit(&stat_);
00230 ilu_set_default_options(&options_);
00231 options_.ILU_DropTol=DropTol_;
00232 options_.ILU_FillTol=FillTol_;
00233 options_.ILU_DropRule=DropRule_;
00234 options_.ILU_FillFactor=FillFactor_;
00235
00236
00237 int *rowptr,*colind;
00238 double *values;
00239 IFPACK_CHK_ERR(Aover_->ExtractCrsDataPointers(rowptr,colind,values));
00240 int N=Aover_->NumMyRows();
00241
00242
00243 dCreate_CompCol_Matrix(&SA_,N,N,Aover_->NumMyNonzeros(),
00244 values,colind,rowptr,SLU_NC,SLU_D,SLU_GE);
00245
00246
00247
00248 dfill_diag(N, (NCformat*)SA_.Store);
00249
00250
00251 etree_=new int [N];
00252 perm_r_=new int[N];
00253 perm_c_=new int[N];
00254
00255
00256 int permc_spec=options_.ColPerm;
00257 if ( permc_spec != MY_PERMC && options_.Fact == DOFACT )
00258 get_perm_c(permc_spec,&SA_,perm_c_);
00259
00260
00261 sp_preorder(&options_, &SA_, perm_c_, etree_, &SAc_);
00262
00263
00264 int panel_size = sp_ienv(1);
00265 int relax = sp_ienv(2);
00266 int info=0;
00267 dgsitrf(&options_,&SAc_,relax,panel_size,etree_,NULL,0,perm_c_,perm_r_,&SL_,&SU_,&stat_,&info);
00268 if(info<0) IFPACK_CHK_ERR(info);
00269
00270 IsComputed_ = true;
00271 NumCompute_++;
00272 ComputeTime_ += Time_.ElapsedTime();
00273 return 0;
00274 }
00275
00276
00277
00278 int Ifpack_SILU::Solve(bool Trans, const Epetra_MultiVector& X,
00279 Epetra_MultiVector& Y) const
00280 {
00281
00282 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
00283 TEUCHOS_FUNC_TIME_MONITOR("Ifpack_SILU::ApplyInverse - Solve");
00284 #endif
00285
00286 if (!IsComputed())
00287 IFPACK_CHK_ERR(-3);
00288 int nrhs=X.NumVectors();
00289 int N=A_->NumMyRows();
00290
00291
00292 Y=X;
00293
00294
00295
00296 if(SY_.Store) Destroy_SuperMatrix_Store(&SY_);
00297 SY_.Store=0;
00298 dCreate_Dense_Matrix(&SY_,N,nrhs,Y[0],N,SLU_DN,SLU_D,SLU_GE);
00299
00300 int info;
00301 dgstrs(TRANS,&SL_,&SU_,perm_c_,perm_r_,&SY_,&stat_,&info);
00302 if(!info) IFPACK_CHK_ERR(info);
00303
00304 return(info);
00305 }
00306
00307
00308
00309 int Ifpack_SILU::Multiply(bool Trans, const Epetra_MultiVector& X,
00310 Epetra_MultiVector& Y) const
00311 {
00312
00313 if (!IsComputed())
00314 IFPACK_CHK_ERR(-1);
00315
00316 return(0);
00317 }
00318
00319
00320
00321 int Ifpack_SILU::ApplyInverse(const Epetra_MultiVector& X,
00322 Epetra_MultiVector& Y) const
00323 {
00324
00325 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
00326 TEUCHOS_FUNC_TIME_MONITOR("Ifpack_SILU::ApplyInverse");
00327 #endif
00328
00329 if (!IsComputed())
00330 IFPACK_CHK_ERR(-3);
00331
00332 if (X.NumVectors() != Y.NumVectors())
00333 IFPACK_CHK_ERR(-2);
00334
00335 Time_.ResetStartTime();
00336
00337
00338
00339 Teuchos::RefCountPtr< const Epetra_MultiVector > Xcopy;
00340 if (X.Pointers()[0] == Y.Pointers()[0])
00341 Xcopy = Teuchos::rcp( new Epetra_MultiVector(X) );
00342 else
00343 Xcopy = Teuchos::rcp( &X, false );
00344
00345 IFPACK_CHK_ERR(Solve(Ifpack_SILU::UseTranspose(), *Xcopy, Y));
00346
00347 ++NumApplyInverse_;
00348 ApplyInverseTime_ += Time_.ElapsedTime();
00349
00350 return(0);
00351
00352 }
00353
00354
00355 double Ifpack_SILU::Condest(const Ifpack_CondestType CT,
00356 const int MaxIters, const double Tol,
00357 Epetra_RowMatrix* Matrix_in)
00358 {
00359
00360 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
00361 TEUCHOS_FUNC_TIME_MONITOR("Ifpack_SILU::Condest");
00362 #endif
00363
00364 if (!IsComputed())
00365 return(-1.0);
00366
00367 Condest_ = Ifpack_Condest(*this, CT, MaxIters, Tol, Matrix_in);
00368
00369 return(Condest_);
00370 }
00371
00372
00373 std::ostream&
00374 Ifpack_SILU::Print(std::ostream& os) const
00375 {
00376 if (!Comm().MyPID()) {
00377 os << endl;
00378 os << "================================================================================" << endl;
00379 os << "Ifpack_SILU: " << Label() << endl << endl;
00380 os << "Dropping rule = "<< DropRule() << endl;
00381 os << "Zero pivot thresh = "<< FillTol() << endl;
00382 os << "Max fill factor = "<< FillFactor() << endl;
00383 os << "Drop tolerance = "<< DropTol() << endl;
00384 os << "Condition number estimate = " << Condest() << endl;
00385 os << "Global number of rows = " << A_->NumGlobalRows() << endl;
00386 if (IsComputed_) {
00387
00388 int fnnz=0;
00389 if(SL_.Store) fnnz+=((SCformat*)SL_.Store)->nnz;
00390 if(SU_.Store) fnnz+=((NCformat*)SU_.Store)->nnz;
00391 int lufill=fnnz - A_->NumMyRows();
00392 os << "No. of nonzeros in L+U = "<< lufill<<endl;
00393 os << "Fill ratio: nnz(F)/nnz(A) = "<<(double)lufill / (double)A_->NumMyNonzeros()<<endl;
00394 }
00395 os << endl;
00396 os << "Phase # calls Total Time (s) Total MFlops MFlops/s" << endl;
00397 os << "----- ------- -------------- ------------ --------" << endl;
00398 os << "Initialize() " << std::setw(5) << NumInitialize()
00399 << " " << std::setw(15) << InitializeTime()
00400 << " 0.0 0.0" << endl;
00401 os << "Compute() " << std::setw(5) << NumCompute()
00402 << " " << std::setw(15) << ComputeTime()
00403 << " " << std::setw(15) << 1.0e-6 * ComputeFlops();
00404 if (ComputeTime() != 0.0)
00405 os << " " << std::setw(15) << 1.0e-6 * ComputeFlops() / ComputeTime() << endl;
00406 else
00407 os << " " << std::setw(15) << 0.0 << endl;
00408 os << "ApplyInverse() " << std::setw(5) << NumApplyInverse()
00409 << " " << std::setw(15) << ApplyInverseTime()
00410 << " " << std::setw(15) << 1.0e-6 * ApplyInverseFlops();
00411 if (ApplyInverseTime() != 0.0)
00412 os << " " << std::setw(15) << 1.0e-6 * ApplyInverseFlops() / ApplyInverseTime() << endl;
00413 else
00414 os << " " << std::setw(15) << 0.0 << endl;
00415 os << "================================================================================" << endl;
00416 os << endl;
00417 }
00418
00419 return(os);
00420 }
00421
00422 #endif