|
Thyra Package Browser (Single Doxygen Collection) Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Epetra: Linear Algebra Services Package 00005 // Copyright (2004) 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 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #include "createTridiagEpetraLinearOp.hpp" 00030 #include "sillyCgSolve.hpp" 00031 #include "Thyra_EpetraThyraWrappers.hpp" 00032 #include "Thyra_EpetraLinearOp.hpp" 00033 #include "Thyra_DefaultSpmdVectorSpace.hpp" 00034 #include "Teuchos_GlobalMPISession.hpp" 00035 #include "Teuchos_CommandLineProcessor.hpp" 00036 #include "Teuchos_VerboseObject.hpp" 00037 #include "Teuchos_StandardCatchMacros.hpp" 00038 00039 // 00040 // Main driver program for epetra implementation of CG. 00041 // 00042 int main(int argc, char *argv[]) 00043 { 00044 using Teuchos::CommandLineProcessor; 00045 using Teuchos::RCP; 00046 00047 bool success = true; 00048 bool verbose = true; 00049 bool result; 00050 00051 // 00052 // (A) Setup and get basic MPI info 00053 // 00054 00055 Teuchos::GlobalMPISession mpiSession(&argc,&argv); 00056 #ifdef HAVE_MPI 00057 MPI_Comm mpiComm = MPI_COMM_WORLD; 00058 #endif 00059 00060 // 00061 // (B) Setup the output stream (do output only on root process!) 00062 // 00063 00064 Teuchos::RCP<Teuchos::FancyOStream> 00065 out = Teuchos::VerboseObjectBase::getDefaultOStream(); 00066 00067 try { 00068 00069 // 00070 // (C) Read in commandline options 00071 // 00072 00073 int globalDim = 500; 00074 double diagScale = 1.001; 00075 bool useWithNonEpetraVectors = false; 00076 double tolerance = 1e-4; 00077 int maxNumIters = 300; 00078 00079 CommandLineProcessor clp(false); // Don't throw exceptions 00080 clp.setOption( "verbose", "quiet", &verbose, "Determines if any output is printed or not." ); 00081 clp.setOption( "global-dim", &globalDim, "Global dimension of the linear system." ); 00082 clp.setOption( "diag-scale", &diagScale, "Scaling of the diagonal to improve conditioning." ); 00083 clp.setOption( "use-with-non-epetra-vectors", "use-with-epetra-vectors", &useWithNonEpetraVectors 00084 , "Use non-epetra vectors with Epetra operator or not." ); 00085 clp.setOption( "tol", &tolerance, "Relative tolerance for linear system solve." ); 00086 clp.setOption( "max-num-iters", &maxNumIters, "Maximum of CG iterations." ); 00087 00088 CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv); 00089 if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return; 00090 00091 TEST_FOR_EXCEPTION( globalDim < 2, std::logic_error, "Error, globalDim=" << globalDim << " < 2 is not allowed!" ); 00092 00093 if(verbose) *out << "\n***\n*** Running CG example using Epetra implementation\n***\n" << std::scientific; 00094 00095 // 00096 // (D) Setup a simple linear system with tridagonal operator: 00097 // 00098 // [ a*2 -1 ] 00099 // [ -1 a*2 -1 ] 00100 // A = [ . . . ] 00101 // [ -1 a*2 -1 ] 00102 // [ -1 a*2 ] 00103 // 00104 // (D.1) Create the tridagonal Epetra matrix operator 00105 if(verbose) *out << "\n(1) Constructing tridagonal Epetra matrix A_epetra of global dimension = " << globalDim << " ...\n"; 00106 RCP<Epetra_Operator> 00107 A_epetra = createTridiagEpetraLinearOp( 00108 globalDim 00109 #ifdef HAVE_MPI 00110 ,mpiComm 00111 #endif 00112 ,diagScale,verbose,*out 00113 ); 00114 // (D.2) Wrap the Epetra_Opertor in a Thyra::EpetraLinearOp object 00115 RCP<const Thyra::LinearOpBase<double> > 00116 A = Thyra::epetraLinearOp(A_epetra); 00117 // (D.3) Create RHS vector b and set to a random value 00118 RCP<const Thyra::VectorSpaceBase<double> > 00119 b_space = A->range(); 00120 // (D.4) Create the RHS vector b and initialize it to a random vector 00121 RCP<Thyra::VectorBase<double> > b = createMember(b_space); 00122 Thyra::seed_randomize<double>(0); 00123 Thyra::randomize( -1.0, +1.0, b.ptr() ); 00124 // (D.5) Create LHS vector x and set to zero 00125 RCP<Thyra::VectorBase<double> > x = createMember(A->domain()); 00126 Thyra::assign( x.ptr(), 0.0 ); 00127 // 00128 // (E) Solve the linear system with the silly CG solver 00129 // 00130 result = sillyCgSolve(*A, *b, maxNumIters, tolerance, x.ptr(), *out); 00131 if(!result) success = false; 00132 // 00133 // (F) Check that the linear system was solved to the specified tolerance 00134 // 00135 RCP<Thyra::VectorBase<double> > r = createMember(A->range()); 00136 Thyra::assign(r.ptr(),*b); // r = b 00137 Thyra::apply(*A,Thyra::NOTRANS,*x,r.ptr(),-1.0,+1.0); // r = -A*x + r 00138 const double r_nrm = Thyra::norm(*r), b_nrm =Thyra:: norm(*b); 00139 const double rel_err = r_nrm/b_nrm, relaxTol = 2.0*tolerance; 00140 result = rel_err <= relaxTol; 00141 if(!result) success = false; 00142 if(verbose) 00143 *out 00144 << "\n||b-A*x||/||b|| = "<<r_nrm<<"/"<<b_nrm<<" = "<<rel_err<<(result?" <= ":" > ") 00145 <<"2.0*tolerance = "<<relaxTol<<": "<<(result?"passed":"failed")<<std::endl; 00146 00147 } 00148 TEUCHOS_STANDARD_CATCH_STATEMENTS(true,*out,success) 00149 00150 if (verbose) { 00151 if(success) *out << "\nCongratulations! All of the tests checked out!\n"; 00152 else *out << "\nOh no! At least one of the tests failed!\n"; 00153 } 00154 00155 return success ? 0 : 1; 00156 00157 } // end main()
1.7.4