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
00043 #include "BelosConfigDefs.hpp"
00044 #include "BelosLinearProblem.hpp"
00045 #include "BelosOutputManager.hpp"
00046 #include "BelosStatusTestMaxIters.hpp"
00047 #include "BelosStatusTestMaxRestarts.hpp"
00048 #include "BelosStatusTestResNorm.hpp"
00049 #include "BelosStatusTestCombo.hpp"
00050 #include "BelosEpetraAdapter.hpp"
00051 #include "BelosBlockGmres.hpp"
00052 #include "createEpetraProblem.hpp"
00053 #include "Ifpack_IlukGraph.h"
00054 #include "Ifpack_CrsRiluk.h"
00055 #include "Epetra_CrsMatrix.h"
00056 #include "Epetra_Map.h"
00057 #include "Teuchos_CommandLineProcessor.hpp"
00058 #include "Teuchos_ParameterList.hpp"
00059
00060 int main(int argc, char *argv[]) {
00061
00062 #ifdef EPETRA_MPI
00063 MPI_Init(&argc,&argv);
00064 Belos::MPIFinalize mpiFinalize;
00065 #endif
00066
00067 typedef double ST;
00068 typedef Teuchos::ScalarTraits<ST> SCT;
00069 typedef SCT::magnitudeType MT;
00070 typedef Belos::MultiVec<ST> MV;
00071 typedef Belos::Operator<ST> OP;
00072 typedef Belos::MultiVecTraits<ST,MV> MVT;
00073 typedef Belos::OperatorTraits<ST,MV,OP> OPT;
00074
00075 using Teuchos::ParameterList;
00076 using Teuchos::RefCountPtr;
00077 using Teuchos::rcp;
00078
00079 bool verbose = false, proc_verbose = false;
00080 int blocksize = 1;
00081 int numrhs = 1;
00082 int numrestarts = 25;
00083 std::string filename("orsirr1.hb");
00084 MT tol = 1.0e-5;
00085
00086 Teuchos::CommandLineProcessor cmdp(false,true);
00087 cmdp.setOption("verbose","quiet",&verbose,"Print messages and results.");
00088 cmdp.setOption("filename",&filename,"Filename for Harwell-Boeing test matrix.");
00089 cmdp.setOption("tol",&tol,"Relative residual tolerance used by GMRES solver.");
00090 cmdp.setOption("num-rhs",&numrhs,"Number of right-hand sides to be solved for.");
00091 cmdp.setOption("num-restarts",&numrestarts,"Number of restarts allowed for GMRES solver.");
00092 cmdp.setOption("block-size",&blocksize,"Block size used by GMRES.");
00093 if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
00094 return -1;
00095 }
00096
00097
00098
00099 int MyPID;
00100 RefCountPtr<Epetra_CrsMatrix> A;
00101 int return_val =Belos::createEpetraProblem(filename,NULL,&A,NULL,NULL,&MyPID);
00102 if(return_val != 0) return return_val;
00103 const Epetra_Map &Map = A->RowMap();
00104 proc_verbose = verbose && (MyPID==0);
00105
00106
00107
00108 if (proc_verbose) cout << endl << endl;
00109 if (proc_verbose) cout << "Constructing ILU preconditioner" << endl;
00110 int Lfill = 0;
00111
00112 if (proc_verbose) cout << "Using Lfill = " << Lfill << endl;
00113 int Overlap = 0;
00114
00115 if (proc_verbose) cout << "Using Level Overlap = " << Overlap << endl;
00116 double Athresh = 0.0;
00117
00118 if (proc_verbose) cout << "Using Absolute Threshold Value of " << Athresh << endl;
00119 double Rthresh = 1.0;
00120
00121 if (proc_verbose) cout << "Using Relative Threshold Value of " << Rthresh << endl;
00122
00123 Teuchos::RefCountPtr<Ifpack_IlukGraph> ilukGraph;
00124 Teuchos::RefCountPtr<Ifpack_CrsRiluk> ilukFactors;
00125
00126 if (Lfill > -1) {
00127 ilukGraph = Teuchos::rcp( new Ifpack_IlukGraph(A->Graph(), Lfill, Overlap) );
00128 assert(ilukGraph->ConstructFilledGraph()==0);
00129 ilukFactors = Teuchos::rcp( new Ifpack_CrsRiluk(*ilukGraph) );
00130 int initerr = ilukFactors->InitValues(*A);
00131 if (initerr != 0) cout << "InitValues error = " << initerr;
00132 assert(ilukFactors->Factor() == 0);
00133 }
00134
00135 bool transA = false;
00136 double Cond_Est;
00137 ilukFactors->Condest(transA, Cond_Est);
00138 if (proc_verbose) {
00139 cout << "Condition number estimate for this preconditoner = " << Cond_Est << endl;
00140 cout << endl;
00141 }
00142
00143
00144
00145
00146
00147 Belos::EpetraOp Amat( A );
00148
00149
00150
00151 Belos::EpetraPrecOp Prec( ilukFactors );
00152
00153
00154
00155
00156 const int NumGlobalElements = Map.NumGlobalElements();
00157 int maxits = NumGlobalElements/blocksize - 1;
00158 int length = 25;
00159
00160 ParameterList My_PL;
00161 My_PL.set( "Length", length );
00162 My_PL.set( "Variant", "Flexible" );
00163
00164
00165
00166 Belos::EpetraMultiVec soln(Map, numrhs);
00167 Belos::EpetraMultiVec rhs(Map, numrhs);
00168 rhs.MvRandom();
00169 Belos::LinearProblem<double,MV,OP>
00170 My_LP( rcp(&Amat,false), rcp(&soln,false), rcp(&rhs,false) );
00171 My_LP.SetRightPrec( rcp(&Prec,false) );
00172
00173 My_LP.SetBlockSize( blocksize );
00174
00175 typedef Belos::StatusTestCombo<double,MV,OP> StatusTestCombo_t;
00176 typedef Belos::StatusTestResNorm<double,MV,OP> StatusTestResNorm_t;
00177 Belos::StatusTestMaxIters<double,MV,OP> test1( maxits );
00178 Belos::StatusTestMaxRestarts<double,MV,OP> test2( numrestarts );
00179 StatusTestCombo_t BasicTest( StatusTestCombo_t::OR, test1, test2 );
00180 StatusTestResNorm_t test3( tol );
00181 test3.DefineScaleForm( StatusTestResNorm_t::NormOfPrecInitRes, Belos::TwoNorm );
00182 BasicTest.AddStatusTest( test3 );
00183 StatusTestResNorm_t ExpTest( tol );
00184 ExpTest.DefineResForm( StatusTestResNorm_t::Explicit, Belos::TwoNorm );
00185 StatusTestCombo_t My_Test( StatusTestCombo_t::SEQ, BasicTest, ExpTest );
00186
00187 Belos::OutputManager<double> My_OM( MyPID );
00188 if (verbose)
00189 My_OM.SetVerbosity( Belos::Errors + Belos::Warnings
00190 + Belos::TimingDetails + Belos::FinalSummary );
00191
00192
00193
00194
00195
00196 Belos::BlockGmres<double,MV,OP>
00197 MyBlockGmres( rcp(&My_LP,false), rcp(&My_Test,false), rcp(&My_OM,false), rcp(&My_PL,false));
00198
00199
00200
00201 if (proc_verbose) {
00202 cout << endl << endl;
00203 cout << "Dimension of matrix: " << NumGlobalElements << endl;
00204 cout << "Number of right-hand sides: " << numrhs << endl;
00205 cout << "Block size used by solver: " << blocksize << endl;
00206 cout << "Number of restarts allowed: " << numrestarts << endl;
00207 cout << "Length of block Arnoldi factorization: " << length*blocksize << " ( "<< length << " blocks ) " <<endl;
00208 cout << "Max number of Gmres iterations: " << maxits << endl;
00209 cout << "Relative residual tolerance: " << tol << endl;
00210 cout << endl;
00211 }
00212
00213
00214 if (proc_verbose) {
00215 cout << endl << endl;
00216 cout << "Running Block Gmres -- please wait" << endl;
00217 cout << (numrhs+blocksize-1)/blocksize
00218 << " pass(es) through the solver required to solve for " << endl;
00219 cout << numrhs << " right-hand side(s) -- using a block size of " << blocksize
00220 << endl << endl;
00221 }
00222
00223
00224
00225
00226 MyBlockGmres.Solve();
00227
00228
00229
00230
00231 std::vector<double> actual_resids( numrhs );
00232 std::vector<double> rhs_norm( numrhs );
00233 Belos::EpetraMultiVec resid(Map, numrhs);
00234 OPT::Apply( Amat, soln, resid );
00235 MVT::MvAddMv( -1.0, resid, 1.0, rhs, resid );
00236 MVT::MvNorm( resid, &actual_resids );
00237 MVT::MvNorm( rhs, &rhs_norm );
00238 if (proc_verbose) {
00239 cout<< "---------- Actual Residuals (normalized) ----------"<<endl<<endl;
00240 for ( int i=0; i<numrhs; i++) {
00241 cout<<"Problem "<<i<<" : \t"<< actual_resids[i]/rhs_norm[i] <<endl;
00242 }
00243 }
00244
00245 if (My_Test.GetStatus()!=Belos::Converged) {
00246 if (proc_verbose)
00247 cout << "End Result: TEST FAILED" << endl;
00248 return -1;
00249 }
00250
00251
00252
00253 if (proc_verbose)
00254 cout << "End Result: TEST PASSED" << endl;
00255 return 0;
00256
00257 }