Stratimikos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxx_main.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Stratimikos: Thyra-based strategies for linear solvers
4 //
5 // Copyright 2006 NTESS and the Stratimikos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 //
11 // This test uses the MVOPTester.hpp functions to test the Belos adapters
12 // to Epetra and Thyra.
13 //
14 
15 #include "Epetra_Map.h"
16 #include "Epetra_CrsMatrix.h"
17 #ifdef HAVE_MPI
18 #include "mpi.h"
19 #include "Epetra_MpiComm.h"
20 #endif
21 #ifndef __cplusplus
22 #define __cplusplus
23 #endif
24 #include "Epetra_Comm.h"
25 #include "Epetra_SerialComm.h"
26 
27 #include "BelosConfigDefs.hpp"
28 #include "BelosMVOPTester.hpp"
29 #include "BelosEpetraAdapter.hpp"
30 
31 #ifdef HAVE_EPETRA_THYRA
32 #include "BelosThyraAdapter.hpp"
34 #include "Thyra_EpetraLinearOp.hpp"
35 #endif
36 
37 
38 
39 int main(int argc, char *argv[])
40 {
41 
42  using Teuchos::rcp_implicit_cast;
43 
44  int i, ierr, gerr;
45  gerr = 0;
46 #ifdef NDEBUG
47  (void)ierr; // Eliminate unused warning
48 #endif
49 
50 #ifdef HAVE_MPI
51  // Initialize MPI and setup an Epetra communicator
52  MPI_Init(&argc,&argv);
53  Teuchos::RCP<Epetra_MpiComm> Comm = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_WORLD) );
54 #else
55  // If we aren't using MPI, then setup a serial communicator.
56  Teuchos::RCP<Epetra_SerialComm> Comm = Teuchos::rcp( new Epetra_SerialComm() );
57 #endif
58 
59 
60  // number of global elements
61  int dim = 100;
62  int blockSize = 3;
63 
64  // PID info
65  int MyPID = Comm->MyPID();
66  bool verbose = 0;
67 
68  if (argc>1) {
69  if (argv[1][0]=='-' && argv[1][1]=='v') {
70  verbose = true;
71  }
72  }
73 
74  // Construct a Map that puts approximately the same number of
75  // equations on each processor.
76  Teuchos::RCP<Epetra_Map> Map = Teuchos::rcp( new Epetra_Map(dim, 0, *Comm) );
77 
78  // Get update list and number of local equations from newly created Map.
79  int NumMyElements = Map->NumMyElements();
80  std::vector<int> MyGlobalElements(NumMyElements);
81  Map->MyGlobalElements(&MyGlobalElements[0]);
82 
83  // Create an integer std::vector NumNz that is used to build the Petra Matrix.
84  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation
85  // on this processor
86  std::vector<int> NumNz(NumMyElements);
87 
88  // We are building a tridiagonal matrix where each row has (-1 2 -1)
89  // So we need 2 off-diagonal terms (except for the first and last equation)
90  for (i=0; i<NumMyElements; i++) {
91  if (MyGlobalElements[i]==0 || MyGlobalElements[i] == dim-1) {
92  NumNz[i] = 2;
93  }
94  else {
95  NumNz[i] = 3;
96  }
97  }
98 
99  // Create an Epetra_Matrix
100  Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *Map, &NumNz[0]) );
101 
102  // Add rows one-at-a-time
103  // Need some vectors to help
104  // Off diagonal Values will always be -1
105  std::vector<double> Values(2);
106  Values[0] = -1.0; Values[1] = -1.0;
107  std::vector<int> Indices(2);
108  double two = 2.0;
109  int NumEntries;
110  for (i=0; i<NumMyElements; i++) {
111  if (MyGlobalElements[i]==0) {
112  Indices[0] = 1;
113  NumEntries = 1;
114  }
115  else if (MyGlobalElements[i] == dim-1) {
116  Indices[0] = dim-2;
117  NumEntries = 1;
118  }
119  else {
120  Indices[0] = MyGlobalElements[i]-1;
121  Indices[1] = MyGlobalElements[i]+1;
122  NumEntries = 2;
123  }
124  ierr = A->InsertGlobalValues(MyGlobalElements[i],NumEntries,&Values[0],&Indices[0]);
125  assert(ierr==0);
126  // Put in the diagonal entry
127  ierr = A->InsertGlobalValues(MyGlobalElements[i],1,&two,&MyGlobalElements[i]);
128  assert(ierr==0);
129  }
130 
131  // Finish building the epetra matrix A
132  ierr = A->FillComplete();
133  assert(ierr==0);
134 
135  // Create an Belos::EpetraOp from this Epetra_CrsMatrix
136  Teuchos::RCP<Belos::EpetraOp> op = Teuchos::rcp(new Belos::EpetraOp(A));
137 
138  // Issue several useful typedefs;
139  // typedef Belos::MultiVec<double> EMV; // unused
140  // typedef Belos::Operator<double> EOP; // unused
141 
142  // Create an Epetra_MultiVector for an initial std::vector to start the solver.
143  // Note that this needs to have the same number of columns as the blocksize.
144  Teuchos::RCP<Belos::EpetraMultiVec> ivec = Teuchos::rcp( new Belos::EpetraMultiVec(*Map, blockSize) );
145  ivec->Random();
146 
147  // Create an output manager to handle the I/O from the solver
148  Teuchos::RCP<Belos::OutputManager<double> > MyOM = Teuchos::rcp( new Belos::OutputManager<double>( MyPID ) );
149  if (verbose) {
150  MyOM->setVerbosity( Belos::Errors + Belos::Warnings );
151  }
152 
153 #ifdef HAVE_EPETRA_THYRA
154  typedef Thyra::MultiVectorBase<double> TMVB;
155  typedef Thyra::LinearOpBase<double> TLOB;
156  // create thyra objects from the epetra objects
157 
158  // first, a Thyra::VectorSpaceBase
161 
162  // then, a MultiVectorBase (from the Epetra_MultiVector)
164  Thyra::create_MultiVector(rcp_implicit_cast<Epetra_MultiVector>(ivec),epetra_vs);
165 
166  // then, a LinearOpBase (from the Epetra_CrsMatrix)
169 
170 
171  // test the Thyra adapter multivector
172  ierr = Belos::TestMultiVecTraits<double,TMVB>(MyOM,thyra_ivec);
173  gerr |= ierr;
174  switch (ierr) {
175  case Belos::Ok:
176  if ( verbose && MyPID==0 ) {
177  std::cout << "*** ThyraAdapter PASSED TestMultiVecTraits()" << std::endl;
178  }
179  break;
180  case Belos::Error:
181  if ( verbose && MyPID==0 ) {
182  std::cout << "*** ThyraAdapter FAILED TestMultiVecTraits() ***"
183  << std::endl << std::endl;
184  }
185  break;
186  }
187 
188  // test the Thyra adapter operator
189  ierr = Belos::TestOperatorTraits<double,TMVB,TLOB>(MyOM,thyra_ivec,thyra_op);
190  gerr |= ierr;
191  switch (ierr) {
192  case Belos::Ok:
193  if ( verbose && MyPID==0 ) {
194  std::cout << "*** ThyraAdapter PASSED TestOperatorTraits()" << std::endl;
195  }
196  break;
197  case Belos::Error:
198  if ( verbose && MyPID==0 ) {
199  std::cout << "*** ThyraAdapter FAILED TestOperatorTraits() ***"
200  << std::endl << std::endl;
201  }
202  break;
203  }
204 #endif
205 
206 #ifdef HAVE_MPI
207  MPI_Finalize();
208 #endif
209 
210  if (gerr) {
211  if (verbose && MyPID==0)
212  std::cout << "End Result: TEST FAILED" << std::endl;
213  return -1;
214  }
215  //
216  // Default return value
217  //
218  if (verbose && MyPID==0)
219  std::cout << "End Result: TEST PASSED" << std::endl;
220  return 0;
221 
222 }
int main(int argc, char *argv[])
RCP< const VectorSpaceBase< double > > create_VectorSpace(const RCP< const Epetra_Map > &epetra_map)
Thyra specializations of MultiVecTraits and OperatorTraits.
RCP< MultiVectorBase< double > > create_MultiVector(const RCP< Epetra_MultiVector > &epetra_mv, const RCP< const VectorSpaceBase< double > > &range=Teuchos::null, const RCP< const VectorSpaceBase< double > > &domain=Teuchos::null)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)