|
Stratimikos Package Browser (Single Doxygen Collection)
Version of the Day
|
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 }
1.7.6.1