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