Thyra Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sillyPowerMethod_epetra.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
4 //
5 // Copyright 2004 NTESS and the Thyra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #include "sillyPowerMethod.hpp"
12 #include "Thyra_TestingTools.hpp"
13 #include "Thyra_EpetraLinearOp.hpp"
19 #include "Teuchos_dyn_cast.hpp"
20 #include "Epetra_CrsMatrix.h"
21 #include "Epetra_Map.h"
22 
23 //
24 // Increase the first diagonal element of your tridiagonal matrix.
25 //
26 void scaleFirstDiagElement( const double diagScale, Thyra::LinearOpBase<double> *A )
27 {
28  using Teuchos::RCP;
29  TEUCHOS_TEST_FOR_EXCEPT(A==NULL);
30  // (A) Get at the underlying Epetra_Operator object that the EpetraLinearOp
31  // object directly maintains.
32  const RCP<Epetra_Operator> epetra_op = Thyra::get_Epetra_Operator(*A);
33  // (B) Perform a dynamic cast to Epetra_CrsMatrix.
34  // Note, the dyn_cast<>() template function will throw std::bad_cast
35  // with a nice error message if the cast fails!
36  Epetra_CrsMatrix &crsMatrix = Teuchos::dyn_cast<Epetra_CrsMatrix>(*epetra_op);
37  // (C) Query if the first row of the matrix is on this processor and if
38  // it is get it and scale it.
39  if(crsMatrix.MyGlobalRow(0)) {
40  const int numRowNz = crsMatrix.NumGlobalEntries(0);
41  TEUCHOS_TEST_FOR_EXCEPT( numRowNz != 2 );
42  int returndNumRowNz; double rowValues[2]; int rowIndexes[2];
43  crsMatrix.ExtractGlobalRowCopy( 0, numRowNz, returndNumRowNz, &rowValues[0], &rowIndexes[0] );
44  TEUCHOS_TEST_FOR_EXCEPT( returndNumRowNz != 2 );
45  for( int k = 0; k < numRowNz; ++k) if (rowIndexes[k] == 0) rowValues[k] *= diagScale;
46  crsMatrix.ReplaceGlobalValues( 0, numRowNz, rowValues, rowIndexes );
47  }
48 } // end scaleFirstDiagElement()
49 
50 //
51 // Main driver program for epetra implementation of the power method.
52 //
53 int main(int argc, char *argv[])
54 {
55 
56  using Teuchos::outArg;
58  using Teuchos::RCP;
59 
60  bool success = true;
61  bool result;
62 
63  //
64  // (A) Setup and get basic MPI info
65  //
66 
67  Teuchos::GlobalMPISession mpiSession(&argc,&argv);
68 #ifdef HAVE_MPI
69  MPI_Comm mpiComm = MPI_COMM_WORLD;
70 #endif
71 
72  //
73  // (B) Setup the output stream (do output only on root process!)
74  //
75 
77  out = Teuchos::VerboseObjectBase::getDefaultOStream();
78 
79  try {
80 
81  //
82  // (C) Read in commandline options
83  //
84 
85 
86  CommandLineProcessor clp;
87  clp.throwExceptions(false);
88  clp.addOutputSetupOptions(true);
89 
90  int globalDim = 500;
91  clp.setOption( "global-dim", &globalDim, "Global dimension of the linear system." );
92 
93  bool dumpAll = false;
94  clp.setOption( "dump-all", "no-dump", &dumpAll, "Determines if quantities are dumped or not." );
95 
96  CommandLineProcessor::EParseCommandLineReturn
97  parse_return = clp.parse(argc,argv);
98  if (parse_return != CommandLineProcessor::PARSE_SUCCESSFUL)
99  return parse_return;
100 
101  TEUCHOS_TEST_FOR_EXCEPTION( globalDim < 2, std::logic_error, "Error, globalDim=" << globalDim << " < 2 is not allowed!" );
102 
103  *out << "\n***\n*** Running power method example using Epetra implementation\n***\n" << std::scientific;
104 
105  //
106  // (D) Setup the operator and run the power method!
107  //
108 
109  //
110  // (1) Setup the initial tridiagonal operator
111  //
112  // [ 2 -1 ]
113  // [ -1 2 -1 ]
114  // A = [ . . . ]
115  // [ -1 2 -1 ]
116  // [ -1 2 ]
117  //
118  *out << "\n(1) Constructing tridagonal Epetra matrix A of global dimension = " << globalDim << " ...\n";
119  RCP<Epetra_Operator>
120  A_epetra = createTridiagEpetraLinearOp(
121  globalDim,
122 #ifdef HAVE_MPI
123  mpiComm,
124 #endif
125  1.0, true, *out
126  );
127  // Wrap in an Thyra::EpetraLinearOp object
128  RCP<Thyra::LinearOpBase<double> >
129  A = Thyra::nonconstEpetraLinearOp(A_epetra);
130  //
131  if (dumpAll) *out << "\nA =\n" << *A; // This works even in parallel!
132 
133  //
134  // (2) Run the power method ANA
135  //
136  *out << "\n(2) Running the power method on matrix A ...\n";
137  double lambda = 0.0;
138  double tolerance = 1e-3;
139  int maxNumIters = 10*globalDim;
140  result = sillyPowerMethod<double>(*A, maxNumIters, tolerance, outArg(lambda), *out);
141  if(!result) success = false;
142  *out << "\n Estimate of dominate eigenvalue lambda = " << lambda << std::endl;
143 
144  //
145  // (3) Increase dominance of first eigenvalue
146  //
147  *out << "\n(3) Scale the diagonal of A by a factor of 10 ...\n";
148  scaleFirstDiagElement( 10.0, &*A );
149 
150  //
151  // (4) Run the power method ANA again
152  //
153  *out << "\n(4) Running the power method again on matrix A ...\n";
154  result = sillyPowerMethod<double>(*A, maxNumIters, tolerance, outArg(lambda), *out);
155  if(!result) success = false;
156  *out << "\n Estimate of dominate eigenvalue lambda = " << lambda << std::endl;
157 
158  }
159  TEUCHOS_STANDARD_CATCH_STATEMENTS(true,*out,success)
160 
161  if (success)
162  *out << "\nCongratulations! All of the tests checked out!\n";
163  else
164  *out << "\nOh no! At least one of the tests failed!\n";
165 
166  return success ? 0 : 1;
167 
168 } // end main()
Teuchos::RCP< Epetra_Operator > createTridiagEpetraLinearOp(const int globalDim, const double diagScale, const bool verbose, std::ostream &out)
This function generates a tridiagonal linear operator using Epetra.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
T_To & dyn_cast(T_From &from)
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
int main(int argc, char *argv[])
void scaleFirstDiagElement(const double diagScale, Thyra::LinearOpBase< double > *A)
Teuchos::RCP< Epetra_Operator > get_Epetra_Operator(LinearOpBase< double > &op)
Full specialization for Scalar=double.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)