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 #include "BelosConfigDefs.hpp"
00036 #include "BelosLinearProblem.hpp"
00037 #include "BelosOutputManager.hpp"
00038 #include "BelosStatusTestMaxIters.hpp"
00039 #include "BelosStatusTestMaxRestarts.hpp"
00040 #include "BelosStatusTestResNorm.hpp"
00041 #include "BelosStatusTestOutputter.hpp"
00042 #include "BelosStatusTestCombo.hpp"
00043 #include "BelosEpetraAdapter.hpp"
00044 #include "BelosBlockGmres.hpp"
00045 #include "createEpetraProblem.hpp"
00046 #include "Epetra_CrsMatrix.h"
00047 #include "Teuchos_CommandLineProcessor.hpp"
00048 #include "Teuchos_ParameterList.hpp"
00049 #include "Epetra_Map.h"
00050
00051 int main(int argc, char *argv[]) {
00052
00053 #ifdef EPETRA_MPI
00054 MPI_Init(&argc,&argv);
00055 Belos::MPIFinalize mpiFinalize;
00056 #endif
00057
00058 typedef double ST;
00059 typedef Teuchos::ScalarTraits<ST> SCT;
00060 typedef SCT::magnitudeType MT;
00061 typedef Epetra_MultiVector MV;
00062 typedef Epetra_Operator OP;
00063 typedef Belos::MultiVecTraits<ST,MV> MVT;
00064 typedef Belos::OperatorTraits<ST,MV,OP> OPT;
00065
00066 using Teuchos::ParameterList;
00067 using Teuchos::RefCountPtr;
00068 using Teuchos::rcp;
00069
00070 bool verbose = false, proc_verbose = false;
00071 int frequency = -1;
00072 int blocksize = 1;
00073 int numrhs = 1;
00074 int numrestarts = 15;
00075 std::string filename("orsirr1.hb");
00076 MT tol = 1.0e-5;
00077
00078 Teuchos::CommandLineProcessor cmdp(false,true);
00079 cmdp.setOption("verbose","quiet",&verbose,"Print messages and results.");
00080 cmdp.setOption("frequency",&frequency,"Solvers frequency for printing residuals (#iters).");
00081 cmdp.setOption("filename",&filename,"Filename for Harwell-Boeing test matrix.");
00082 cmdp.setOption("tol",&tol,"Relative residual tolerance used by GMRES solver.");
00083 cmdp.setOption("num-restarts",&numrestarts,"Number of restarts allowed for GMRES solver.");
00084 cmdp.setOption("block-size",&blocksize,"Block size used by GMRES.");
00085 if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
00086 return -1;
00087 }
00088 if (!verbose)
00089 frequency = -1;
00090
00091
00092
00093 int MyPID;
00094 RefCountPtr<Epetra_CrsMatrix> A;
00095 RefCountPtr<Epetra_MultiVector> B, X;
00096 int return_val =Belos::createEpetraProblem(filename,NULL,&A,&B,&X,&MyPID);
00097 if(return_val != 0) return return_val;
00098 const Epetra_Map &Map = A->RowMap();
00099 proc_verbose = verbose && (MyPID==0);
00100
00101
00102
00103
00104 const int NumGlobalElements = B->GlobalLength();
00105 int maxits = NumGlobalElements/blocksize - 1;
00106
00107 ParameterList My_PL;
00108 My_PL.set( "Length", maxits );
00109
00110
00111
00112 Belos::LinearProblem<double,MV,OP>
00113 My_LP( A, X, B );
00114 My_LP.SetBlockSize( blocksize );
00115
00116
00117
00118
00119
00120 Belos::OutputManager<double> My_OM( MyPID );
00121 if (verbose)
00122 My_OM.SetVerbosity( Belos::Errors + Belos::Warnings
00123 + Belos::TimingDetails + Belos::FinalSummary );
00124
00125 typedef Belos::StatusTestCombo<double,MV,OP> StatusTestCombo_t;
00126 Belos::StatusTestMaxIters<double,MV,OP> test1( maxits );
00127 Belos::StatusTestMaxRestarts<double,MV,OP> test2( numrestarts );
00128 StatusTestCombo_t test3( StatusTestCombo_t::OR, test1, test2 );
00129 Belos::StatusTestResNorm<double,MV,OP> test4( tol );
00130 Belos::StatusTestOutputter<ST,MV,OP> test5( frequency, false );
00131 test5.set_resNormStatusTest( rcp(&test4,false) );
00132 test5.set_outputManager( rcp(&My_OM,false) );
00133 StatusTestCombo_t My_Test( StatusTestCombo_t::OR, test3, test5 );
00134
00135 Belos::BlockGmres<double,MV,OP>
00136 MyBlockGmres( rcp(&My_LP,false), rcp(&My_Test,false), rcp(&My_OM,false), rcp(&My_PL,false));
00137
00138
00139
00140
00141 if (proc_verbose) {
00142 cout << endl << endl;
00143 cout << "Dimension of matrix: " << NumGlobalElements << endl;
00144 cout << "Number of right-hand sides: " << numrhs << endl;
00145 cout << "Block size used by solver: " << blocksize << endl;
00146 cout << "Number of restarts allowed: " << numrestarts << endl;
00147 cout << "Max number of Gmres iterations per restart cycle: " << maxits << endl;
00148 cout << "Relative residual tolerance: " << tol << endl;
00149 cout << endl;
00150 }
00151
00152
00153 if (proc_verbose) {
00154 cout << endl << endl;
00155 cout << "Running Block Gmres -- please wait" << endl;
00156 cout << (numrhs+blocksize-1)/blocksize
00157 << " pass(es) through the solver required to solve for " << endl;
00158 cout << numrhs << " right-hand side(s) -- using a block size of " << blocksize
00159 << endl << endl;
00160 }
00161
00162
00163
00164
00165 MyBlockGmres.Solve();
00166
00167
00168
00169
00170 std::vector<double> actual_resids( numrhs );
00171 std::vector<double> rhs_norm( numrhs );
00172 Epetra_MultiVector resid(Map, numrhs);
00173 OPT::Apply( *A, *X, resid );
00174 MVT::MvAddMv( -1.0, resid, 1.0, *B, resid );
00175 MVT::MvNorm( resid, &actual_resids );
00176 MVT::MvNorm( *B, &rhs_norm );
00177 if (proc_verbose) {
00178 cout<< "---------- Actual Residuals (normalized) ----------"<<endl<<endl;
00179 for ( int i=0; i<numrhs; i++) {
00180 cout<<"Problem "<<i<<" : \t"<< actual_resids[i]/rhs_norm[i] <<endl;
00181 }
00182 }
00183
00184 if (My_Test.GetStatus()!=Belos::Converged) {
00185 if (proc_verbose)
00186 cout << "End Result: TEST FAILED" << endl;
00187 return -1;
00188 }
00189
00190
00191
00192 if (proc_verbose)
00193 cout << "End Result: TEST PASSED" << endl;
00194 return 0;
00195
00196 }