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