Stratimikos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
cxx_main.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //         Stratimikos: Thyra-based strategies for linear solvers
00005 //                Copyright (2006) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00038 // 
00039 // ***********************************************************************
00040 // @HEADER
00041 //
00042 //  This test uses the MVOPTester.hpp functions to test the Belos adapters
00043 //  to Epetra and Thyra.
00044 //
00045 
00046 #include "Epetra_Map.h"
00047 #include "Epetra_CrsMatrix.h"
00048 #ifdef HAVE_MPI
00049 #include "mpi.h"
00050 #include "Epetra_MpiComm.h"
00051 #endif
00052 #ifndef __cplusplus
00053 #define __cplusplus
00054 #endif
00055 #include "Epetra_Comm.h"
00056 #include "Epetra_SerialComm.h"
00057 
00058 #include "BelosConfigDefs.hpp"
00059 #include "BelosMVOPTester.hpp"
00060 #include "BelosEpetraAdapter.hpp"
00061 
00062 #ifdef HAVE_EPETRA_THYRA
00063 #include "BelosThyraAdapter.hpp"
00064 #include "Thyra_EpetraThyraWrappers.hpp"
00065 #include "Thyra_EpetraLinearOp.hpp"
00066 #endif
00067 
00068 
00069 
00070 int main(int argc, char *argv[])
00071 {
00072   
00073   using Teuchos::rcp_implicit_cast;
00074 
00075   int i, ierr, gerr;
00076   gerr = 0;
00077 
00078 #ifdef HAVE_MPI
00079   // Initialize MPI and setup an Epetra communicator
00080   MPI_Init(&argc,&argv);
00081   Teuchos::RCP<Epetra_MpiComm> Comm = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_WORLD) );
00082 #else
00083   // If we aren't using MPI, then setup a serial communicator.
00084   Teuchos::RCP<Epetra_SerialComm> Comm = Teuchos::rcp( new Epetra_SerialComm() );
00085 #endif
00086 
00087 
00088    // number of global elements
00089   int dim = 100;
00090   int blockSize = 3;
00091 
00092   // PID info
00093   int MyPID = Comm->MyPID();
00094   bool verbose = 0;
00095 
00096   if (argc>1) {
00097     if (argv[1][0]=='-' && argv[1][1]=='v') {
00098       verbose = true;
00099     }
00100   }
00101 
00102   // Construct a Map that puts approximately the same number of 
00103   // equations on each processor.
00104   Teuchos::RCP<Epetra_Map> Map = Teuchos::rcp( new Epetra_Map(dim, 0, *Comm) );
00105   
00106   // Get update list and number of local equations from newly created Map.
00107   int NumMyElements = Map->NumMyElements();
00108   std::vector<int> MyGlobalElements(NumMyElements);
00109   Map->MyGlobalElements(&MyGlobalElements[0]);
00110 
00111   // Create an integer std::vector NumNz that is used to build the Petra Matrix.
00112   // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation 
00113   // on this processor
00114   std::vector<int> NumNz(NumMyElements);
00115 
00116   // We are building a tridiagonal matrix where each row has (-1 2 -1)
00117   // So we need 2 off-diagonal terms (except for the first and last equation)
00118   for (i=0; i<NumMyElements; i++) {
00119     if (MyGlobalElements[i]==0 || MyGlobalElements[i] == dim-1) {
00120       NumNz[i] = 2;
00121     }
00122     else {
00123       NumNz[i] = 3;
00124     }
00125   }
00126 
00127   // Create an Epetra_Matrix
00128   Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *Map, &NumNz[0]) );
00129    
00130   // Add  rows one-at-a-time
00131   // Need some vectors to help
00132   // Off diagonal Values will always be -1
00133   std::vector<double> Values(2);
00134   Values[0] = -1.0; Values[1] = -1.0;
00135   std::vector<int> Indices(2);
00136   double two = 2.0;
00137   int NumEntries;
00138   for (i=0; i<NumMyElements; i++) {
00139     if (MyGlobalElements[i]==0) {
00140       Indices[0] = 1;
00141       NumEntries = 1;
00142     }
00143     else if (MyGlobalElements[i] == dim-1) {
00144       Indices[0] = dim-2;
00145       NumEntries = 1;
00146     }
00147     else {
00148       Indices[0] = MyGlobalElements[i]-1;
00149       Indices[1] = MyGlobalElements[i]+1;
00150       NumEntries = 2;
00151     }
00152     ierr = A->InsertGlobalValues(MyGlobalElements[i],NumEntries,&Values[0],&Indices[0]);
00153     assert(ierr==0);
00154     // Put in the diagonal entry
00155     ierr = A->InsertGlobalValues(MyGlobalElements[i],1,&two,&MyGlobalElements[i]);
00156     assert(ierr==0);
00157   }
00158    
00159   // Finish building the epetra matrix A
00160   ierr = A->FillComplete();
00161   assert(ierr==0);
00162 
00163   // Create an Belos::EpetraOp from this Epetra_CrsMatrix
00164   Teuchos::RCP<Belos::EpetraOp> op = Teuchos::rcp(new Belos::EpetraOp(A));
00165 
00166   // Issue several useful typedefs;
00167   typedef Belos::MultiVec<double> EMV;
00168   typedef Belos::Operator<double> EOP;
00169 
00170   // Create an Epetra_MultiVector for an initial std::vector to start the solver.
00171   // Note that this needs to have the same number of columns as the blocksize.
00172   Teuchos::RCP<Belos::EpetraMultiVec> ivec = Teuchos::rcp( new Belos::EpetraMultiVec(*Map, blockSize) );
00173   ivec->Random();
00174 
00175   // Create an output manager to handle the I/O from the solver
00176   Teuchos::RCP<Belos::OutputManager<double> > MyOM = Teuchos::rcp( new Belos::OutputManager<double>( MyPID ) );
00177   if (verbose) {
00178     MyOM->setVerbosity( Belos::Errors + Belos::Warnings );
00179   }
00180 
00181 #ifdef HAVE_EPETRA_THYRA
00182   typedef Thyra::MultiVectorBase<double> TMVB;
00183   typedef Thyra::LinearOpBase<double>    TLOB;
00184   // create thyra objects from the epetra objects
00185 
00186   // first, a Thyra::VectorSpaceBase
00187   Teuchos::RCP<const Thyra::VectorSpaceBase<double> > epetra_vs = 
00188     Thyra::create_VectorSpace(Map);
00189 
00190   // then, a MultiVectorBase (from the Epetra_MultiVector)
00191   Teuchos::RCP<Thyra::MultiVectorBase<double> > thyra_ivec = 
00192     Thyra::create_MultiVector(rcp_implicit_cast<Epetra_MultiVector>(ivec),epetra_vs);
00193 
00194   // then, a LinearOpBase (from the Epetra_CrsMatrix)
00195   Teuchos::RCP<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       std::cout << "*** ThyraAdapter PASSED TestMultiVecTraits()" << std::endl;
00206     }
00207     break;
00208   case Belos::Error:
00209     if ( verbose && MyPID==0 ) {
00210       std::cout << "*** ThyraAdapter FAILED TestMultiVecTraits() ***" 
00211            << std::endl << std::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       std::cout << "*** ThyraAdapter PASSED TestOperatorTraits()" << std::endl;
00223     }
00224     break;
00225   case Belos::Error:
00226     if ( verbose && MyPID==0 ) {
00227       std::cout << "*** ThyraAdapter FAILED TestOperatorTraits() ***" 
00228            << std::endl << std::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       std::cout << "End Result: TEST FAILED" << std::endl;  
00241     return -1;
00242   }
00243   //
00244   // Default return value
00245   //
00246   if (verbose && MyPID==0)
00247     std::cout << "End Result: TEST PASSED" << std::endl;
00248   return 0;
00249 
00250 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines