test/MVOPTester/cxx_main.cpp

Go to the documentation of this file.
00001 //@HEADER
00002 // ************************************************************************
00003 // 
00004 //
00005 //                 Belos: Block Linear Solvers Package
00006 //                 Copyright (2004) Sandia Corporation
00007 // 
00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00009 // license for use of this work by or on behalf of the U.S. Government.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //  
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA
00025 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00026 // 
00027 // ************************************************************************
00028 //@HEADER
00029 //
00030 //  This test uses the MVOPTester.hpp functions to test the Belos adapters
00031 //  to Epetra and Thyra.
00032 //
00033 
00034 #include "Epetra_Map.h"
00035 #include "Epetra_CrsMatrix.h"
00036 #ifdef HAVE_MPI
00037 #include "mpi.h"
00038 #include "Epetra_MpiComm.h"
00039 #endif
00040 #ifndef __cplusplus
00041 #define __cplusplus
00042 #endif
00043 #include "Epetra_Comm.h"
00044 #include "Epetra_SerialComm.h"
00045 
00046 #include "BelosConfigDefs.hpp"
00047 #include "BelosMVOPTester.hpp"
00048 #include "BelosEpetraAdapter.hpp"
00049 
00050 int main(int argc, char *argv[])
00051 {
00052   int i, ierr, gerr;
00053   gerr = 0;
00054 
00055 #ifdef HAVE_MPI
00056   // Initialize MPI and setup an Epetra communicator
00057   MPI_Init(&argc,&argv);
00058   Teuchos::RefCountPtr<Epetra_MpiComm> Comm = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_WORLD) );
00059 #else
00060   // If we aren't using MPI, then setup a serial communicator.
00061   Teuchos::RefCountPtr<Epetra_SerialComm> Comm = Teuchos::rcp( new Epetra_SerialComm() );
00062 #endif
00063 
00064    // number of global elements
00065   int dim = 100;
00066   int blockSize = 5;
00067 
00068   // PID info
00069   int MyPID = Comm->MyPID();
00070   bool verbose = 0;
00071 
00072   if (argc>1) {
00073     if (argv[1][0]=='-' && argv[1][1]=='v') {
00074       verbose = true;
00075     }
00076   }
00077 
00078   // Construct a Map that puts approximately the same number of 
00079   // equations on each processor.
00080   Teuchos::RefCountPtr<Epetra_Map> Map = Teuchos::rcp( new Epetra_Map(dim, 0, *Comm) );
00081   
00082   // Get update list and number of local equations from newly created Map.
00083   int NumMyElements = Map->NumMyElements();
00084   std::vector<int> MyGlobalElements(NumMyElements);
00085   Map->MyGlobalElements(&MyGlobalElements[0]);
00086 
00087   // Create an integer vector NumNz that is used to build the Petra Matrix.
00088   // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation 
00089   // on this processor
00090   std::vector<int> NumNz(NumMyElements);
00091 
00092   // We are building a tridiagonal matrix where each row has (-1 2 -1)
00093   // So we need 2 off-diagonal terms (except for the first and last equation)
00094   for (i=0; i<NumMyElements; i++) {
00095     if (MyGlobalElements[i]==0 || MyGlobalElements[i] == dim-1) {
00096       NumNz[i] = 2;
00097     }
00098     else {
00099       NumNz[i] = 3;
00100     }
00101   }
00102 
00103   // Create an Epetra_Matrix
00104   Teuchos::RefCountPtr<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *Map, &NumNz[0]) );
00105    
00106   // Add  rows one-at-a-time
00107   // Need some vectors to help
00108   // Off diagonal Values will always be -1
00109   std::vector<double> Values(2);
00110   Values[0] = -1.0; Values[1] = -1.0;
00111   std::vector<int> Indices(2);
00112   double two = 2.0;
00113   int NumEntries;
00114   for (i=0; i<NumMyElements; i++) {
00115     if (MyGlobalElements[i]==0) {
00116       Indices[0] = 1;
00117       NumEntries = 1;
00118     }
00119     else if (MyGlobalElements[i] == dim-1) {
00120       Indices[0] = dim-2;
00121       NumEntries = 1;
00122     }
00123     else {
00124       Indices[0] = MyGlobalElements[i]-1;
00125       Indices[1] = MyGlobalElements[i]+1;
00126       NumEntries = 2;
00127     }
00128     ierr = A->InsertGlobalValues(MyGlobalElements[i],NumEntries,&Values[0],&Indices[0]);
00129     assert(ierr==0);
00130     // Put in the diagonal entry
00131     ierr = A->InsertGlobalValues(MyGlobalElements[i],1,&two,&MyGlobalElements[i]);
00132     assert(ierr==0);
00133   }
00134    
00135   // Finish building the epetra matrix A
00136   ierr = A->FillComplete();
00137   assert(ierr==0);
00138 
00139   // Create an Belos::Op from this Epetra_CrsMatrix
00140   Teuchos::RefCountPtr<Belos::EpetraOp> op = Teuchos::rcp(new Belos::EpetraOp(A));
00141 
00142   // Issue several useful typedefs;
00143   typedef Belos::MultiVec<double> EMV;
00144   typedef Belos::Operator<double> EOP;
00145 
00146   // Create an Epetra_MultiVector for an initial vector to start the solver.
00147   // Note that this needs to have the same number of columns as the blocksize.
00148   Teuchos::RefCountPtr<Belos::EpetraMultiVec> ivec = Teuchos::rcp( new Belos::EpetraMultiVec(*Map, blockSize) );
00149   ivec->Random();
00150 
00151   // Create an output manager to handle the I/O from the solver
00152   Teuchos::RefCountPtr<Belos::OutputManager<double> > MyOM = Teuchos::rcp( new Belos::OutputManager<double>( MyPID ) );
00153   if (verbose) {
00154     MyOM->SetVerbosity( Belos::Errors + Belos::Warnings );
00155   }
00156 
00157   // test the Epetra adapter multivector
00158   ierr = Belos::TestMultiVecTraits<double,EMV>(MyOM,ivec);
00159   gerr |= ierr;
00160   switch (ierr) {
00161   case Belos::Ok:
00162     if ( verbose && MyPID==0 ) {
00163       cout << "*** EpetraAdapter PASSED TestMultiVecTraits()" << endl;
00164     }
00165     break;
00166   case Belos::Error:
00167     if ( verbose && MyPID==0 ) {
00168       cout << "*** EpetraAdapter FAILED TestMultiVecTraits() ***" 
00169            << endl << endl;
00170     }
00171     break;
00172   }
00173 
00174   // test the Epetra adapter operator 
00175   ierr = Belos::TestOperatorTraits<double,EMV,EOP>(MyOM,ivec,op);
00176   gerr |= ierr;
00177   switch (ierr) {
00178   case Belos::Ok:
00179     if ( verbose && MyPID==0 ) {
00180       cout << "*** EpetraAdapter PASSED TestOperatorTraits()" << endl;
00181     }
00182     break;
00183   case Belos::Error:
00184     if ( verbose && MyPID==0 ) {
00185       cout << "*** EpetraAdapter FAILED TestOperatorTraits() ***" 
00186            << endl << endl;
00187     }
00188     break;
00189   }
00190 
00191 
00192 #ifdef HAVE_MPI
00193   MPI_Finalize();
00194 #endif
00195 
00196   if (gerr) {
00197     if (verbose && MyPID==0)
00198       cout << "End Result: TEST FAILED" << endl;  
00199     return -1;
00200   }
00201   //
00202   // Default return value
00203   //
00204   if (verbose && MyPID==0)
00205     cout << "End Result: TEST PASSED" << endl;
00206   return 0;
00207 
00208 }

Generated on Thu Sep 18 12:30:21 2008 for Belos Package Browser (Single Doxygen Collection) by doxygen 1.3.9.1