thyra/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 #ifdef HAVE_EPETRA_THYRA
00051 #include "BelosThyraAdapter.hpp"
00052 #include "Thyra_EpetraThyraWrappers.hpp"
00053 #include "Thyra_EpetraLinearOp.hpp"
00054 #endif
00055 
00056 using namespace std;
00057 
00058 int main(int argc, char *argv[])
00059 {
00060   int i, ierr, gerr;
00061   gerr = 0;
00062 
00063 #ifdef HAVE_MPI
00064   // Initialize MPI and setup an Epetra communicator
00065   MPI_Init(&argc,&argv);
00066   Teuchos::RefCountPtr<Epetra_MpiComm> Comm = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_WORLD) );
00067 #else
00068   // If we aren't using MPI, then setup a serial communicator.
00069   Teuchos::RefCountPtr<Epetra_SerialComm> Comm = Teuchos::rcp( new Epetra_SerialComm() );
00070 #endif
00071 
00072 
00073    // number of global elements
00074   int dim = 100;
00075   int blockSize = 3;
00076 
00077   // PID info
00078   int MyPID = Comm->MyPID();
00079   bool verbose = 0;
00080 
00081   if (argc>1) {
00082     if (argv[1][0]=='-' && argv[1][1]=='v') {
00083       verbose = true;
00084     }
00085   }
00086 
00087 #ifndef HAVE_EPETRA_THYRA
00088   if (verbose && MyPid == 0) {
00089       cout << "Please configure Belos with:" << endl;
00090       cout << "--enable-epetra-thyra" << endl;
00091       cout << "--enable-anasazi-thyra" << endl;
00092   }
00093   return 0;
00094 #endif
00095 
00096   // Construct a Map that puts approximately the same number of 
00097   // equations on each processor.
00098   Teuchos::RefCountPtr<Epetra_Map> Map = Teuchos::rcp( new Epetra_Map(dim, 0, *Comm) );
00099   
00100   // Get update list and number of local equations from newly created Map.
00101   int NumMyElements = Map->NumMyElements();
00102   std::vector<int> MyGlobalElements(NumMyElements);
00103   Map->MyGlobalElements(&MyGlobalElements[0]);
00104 
00105   // Create an integer vector NumNz that is used to build the Petra Matrix.
00106   // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation 
00107   // on this processor
00108   std::vector<int> NumNz(NumMyElements);
00109 
00110   // We are building a tridiagonal matrix where each row has (-1 2 -1)
00111   // So we need 2 off-diagonal terms (except for the first and last equation)
00112   for (i=0; i<NumMyElements; i++) {
00113     if (MyGlobalElements[i]==0 || MyGlobalElements[i] == dim-1) {
00114       NumNz[i] = 2;
00115     }
00116     else {
00117       NumNz[i] = 3;
00118     }
00119   }
00120 
00121   // Create an Epetra_Matrix
00122   Teuchos::RefCountPtr<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *Map, &NumNz[0]) );
00123    
00124   // Add  rows one-at-a-time
00125   // Need some vectors to help
00126   // Off diagonal Values will always be -1
00127   std::vector<double> Values(2);
00128   Values[0] = -1.0; Values[1] = -1.0;
00129   std::vector<int> Indices(2);
00130   double two = 2.0;
00131   int NumEntries;
00132   for (i=0; i<NumMyElements; i++) {
00133     if (MyGlobalElements[i]==0) {
00134       Indices[0] = 1;
00135       NumEntries = 1;
00136     }
00137     else if (MyGlobalElements[i] == dim-1) {
00138       Indices[0] = dim-2;
00139       NumEntries = 1;
00140     }
00141     else {
00142       Indices[0] = MyGlobalElements[i]-1;
00143       Indices[1] = MyGlobalElements[i]+1;
00144       NumEntries = 2;
00145     }
00146     ierr = A->InsertGlobalValues(MyGlobalElements[i],NumEntries,&Values[0],&Indices[0]);
00147     assert(ierr==0);
00148     // Put in the diagonal entry
00149     ierr = A->InsertGlobalValues(MyGlobalElements[i],1,&two,&MyGlobalElements[i]);
00150     assert(ierr==0);
00151   }
00152    
00153   // Finish building the epetra matrix A
00154   ierr = A->FillComplete();
00155   assert(ierr==0);
00156 
00157   // Create an Belos::EpetraOp from this Epetra_CrsMatrix
00158   Teuchos::RefCountPtr<Belos::EpetraOp> op = Teuchos::rcp(new Belos::EpetraOp(A));
00159 
00160   // Issue several useful typedefs;
00161   typedef Belos::MultiVec<double> EMV;
00162   typedef Belos::Operator<double> EOP;
00163 
00164   // Create an Epetra_MultiVector for an initial vector to start the solver.
00165   // Note that this needs to have the same number of columns as the blocksize.
00166   Teuchos::RefCountPtr<Belos::EpetraMultiVec> ivec = Teuchos::rcp( new Belos::EpetraMultiVec(*Map, blockSize) );
00167   ivec->Random();
00168 
00169   // Create an output manager to handle the I/O from the solver
00170   Teuchos::RefCountPtr<Belos::OutputManager<double> > MyOM = Teuchos::rcp( new Belos::OutputManager<double>( MyPID ) );
00171   if (verbose) {
00172     MyOM->SetVerbosity( Belos::Errors + Belos::Warnings );
00173   }
00174 
00175 #ifdef HAVE_EPETRA_THYRA
00176   typedef Thyra::MultiVectorBase<double> TMVB;
00177   typedef Thyra::LinearOpBase<double>    TLOB;
00178   // create thyra objects from the epetra objects
00179 
00180   // first, a Thyra::VectorSpaceBase
00181   Teuchos::RefCountPtr<const Thyra::SpmdVectorSpaceBase<double> > epetra_vs = 
00182     Thyra::create_VectorSpace(Map);
00183 
00184   // then, a ScalarProdVectorSpaceBase
00185   Teuchos::RefCountPtr<const Thyra::ScalarProdVectorSpaceBase<double> > sp_domain = 
00186     Teuchos::rcp_dynamic_cast<const Thyra::ScalarProdVectorSpaceBase<double> >(
00187       epetra_vs->smallVecSpcFcty()->createVecSpc(ivec->NumVectors())
00188     );
00189 
00190   // then, a MultiVectorBase (from the Epetra_MultiVector)
00191   Teuchos::RefCountPtr<Thyra::MultiVectorBase<double> > thyra_ivec = 
00192     Thyra::create_MultiVector(Teuchos::rcp_implicit_cast<Epetra_MultiVector>(ivec),epetra_vs,sp_domain);
00193 
00194   // then, a LinearOpBase (from the Epetra_CrsMatrix)
00195   Teuchos::RefCountPtr<Thyra::LinearOpBase<double> > thyra_op = 
00196     Teuchos::rcp( new Thyra::EpetraLinearOp(A) );
00197 
00198 
00199   // test the Thyra adapter multivector
00200   ierr = Belos::TestMultiVecTraits<double,TMVB>(MyOM,thyra_ivec);
00201   gerr |= ierr;
00202   switch (ierr) {
00203   case Belos::Ok:
00204     if ( verbose && MyPID==0 ) {
00205       cout << "*** ThyraAdapter PASSED TestMultiVecTraits()" << endl;
00206     }
00207     break;
00208   case Belos::Error:
00209     if ( verbose && MyPID==0 ) {
00210       cout << "*** ThyraAdapter FAILED TestMultiVecTraits() ***" 
00211            << endl << endl;
00212     }
00213     break;
00214   }
00215 
00216   // test the Thyra adapter operator 
00217   ierr = Belos::TestOperatorTraits<double,TMVB,TLOB>(MyOM,thyra_ivec,thyra_op);
00218   gerr |= ierr;
00219   switch (ierr) {
00220   case Belos::Ok:
00221     if ( verbose && MyPID==0 ) {
00222       cout << "*** ThyraAdapter PASSED TestOperatorTraits()" << endl;
00223     }
00224     break;
00225   case Belos::Error:
00226     if ( verbose && MyPID==0 ) {
00227       cout << "*** ThyraAdapter FAILED TestOperatorTraits() ***" 
00228            << endl << endl;
00229     }
00230     break;
00231   }
00232 #endif
00233 
00234 #ifdef HAVE_MPI
00235   MPI_Finalize();
00236 #endif
00237 
00238   if (gerr) {
00239     if (verbose && MyPID==0)
00240       cout << "End Result: TEST FAILED" << endl;  
00241     return -1;
00242   }
00243   //
00244   // Default return value
00245   //
00246   if (verbose && MyPID==0)
00247     cout << "End Result: TEST PASSED" << endl;
00248   return 0;
00249 
00250 }

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