Stratimikos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Thyra_Belos_StatusTest_UnitTests.cpp
Go to the documentation of this file.
00001 /*
00002 // @HEADER
00003 // ***********************************************************************
00004 // 
00005 //         Stratimikos: Thyra-based strategies for linear solvers
00006 //                Copyright (2006) Sandia Corporation
00007 // 
00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00009 // license for use of this work by or on behalf of the U.S. Government.
00010 // 
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00039 // 
00040 // ***********************************************************************
00041 // @HEADER
00042 */
00043 
00044 #include "Thyra_BelosLinearOpWithSolveFactory.hpp"
00045 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
00046 #include "Thyra_MultiVectorStdOps.hpp"
00047 #include "Thyra_VectorBase.hpp"
00048 #include "Thyra_VectorStdOps.hpp"
00049 #include "Thyra_EpetraLinearOp.hpp"
00050 #include "EpetraExt_readEpetraLinearSystem.h"
00051 #include "Epetra_SerialComm.h"
00052 #include "Teuchos_XMLParameterListHelpers.hpp"
00053 #include "Teuchos_toString.hpp"
00054 
00055 #include "Teuchos_UnitTestHarness.hpp"
00056 
00057 
00058 namespace Thyra {
00059 
00060 
00061 //
00062 // Helper code
00063 //
00064 
00065 
00066 const std::string matrixFileName = "nos1.mtx";
00067 
00068 
00069 RCP<const LinearOpBase<double> > getFwdLinearOp()
00070 {
00071   static RCP<const LinearOpBase<double> > fwdLinearOp;
00072   if (is_null(fwdLinearOp)) {
00073     Teuchos::RCP<Epetra_CrsMatrix> epetraCrsMatrix;
00074     EpetraExt::readEpetraLinearSystem( matrixFileName, Epetra_SerialComm(), &epetraCrsMatrix );
00075     fwdLinearOp = epetraLinearOp(epetraCrsMatrix);
00076   }
00077   return fwdLinearOp;
00078 }
00079 
00080 
00082 template<class Scalar>
00083 class MockNormInfReductionFunctional : public ReductionFunctional<Scalar> {
00084 protected:
00085 
00088 
00090   virtual typename ScalarTraits<Scalar>::magnitudeType
00091   reduceImpl(const VectorBase<Scalar> &v) const
00092     { return norm_inf(v); }
00093 
00095   virtual bool isCompatibleImpl( const VectorBase<Scalar> &v ) const
00096     { return true; }
00097 
00099 
00100 };
00101 
00102 
00107 template<class Scalar>
00108 RCP<MockNormInfReductionFunctional<Scalar> >
00109 createMockNormReductionFunctional()
00110 {
00111   return Teuchos::rcp(new MockNormInfReductionFunctional<Scalar>());
00112 }
00113 
00114 
00117 template<class Scalar>
00118 class MockMaxNormInfEpsReductionFunctional : public ReductionFunctional<Scalar> {
00119 protected:
00120 
00123 
00125   virtual typename ScalarTraits<Scalar>::magnitudeType
00126   reduceImpl(const VectorBase<Scalar> &v) const
00127     {
00128       typedef typename ScalarTraits<Scalar>::magnitudeType ScalarMag;
00129       return std::max(norm_inf(v), ScalarTraits<ScalarMag>::eps());
00130     }
00131 
00133   virtual bool isCompatibleImpl( const VectorBase<Scalar> &v ) const
00134     { return true; }
00135 
00137 
00138 };
00139 
00140 
00145 template<class Scalar>
00146 RCP<MockMaxNormInfEpsReductionFunctional<Scalar> >
00147 createMockMaxNormInfEpsReductionFunctional()
00148 {
00149   return Teuchos::rcp(new MockMaxNormInfEpsReductionFunctional<Scalar>());
00150 }
00151 
00152 
00153 template<class Scalar>
00154 void runGeneralSolveCriteriaBelosStatusTestCase(
00155   const SolveCriteria<Scalar> &solveCriteria,
00156   const Ptr<RCP<const VectorBase<Scalar> > > &x_out,
00157   const Ptr<RCP<const VectorBase<Scalar> > > &r_out,
00158   bool &success,
00159   FancyOStream &out
00160   )
00161 {
00162 
00163   using Teuchos::describe; using Teuchos::optInArg; using Teuchos::rcpFromRef;
00164   using Teuchos::toString;
00165 
00166   typedef ScalarTraits<Scalar> ST;
00167   typedef typename ST::magnitudeType ScalarMag;
00168 
00169   // A) Set up the linear system
00170   
00171   const RCP<const LinearOpBase<Scalar> > fwdOp = getFwdLinearOp();
00172   out << "\nfwdOp = " << describe(*fwdOp, Teuchos::VERB_MEDIUM) << "\n";
00173   const RCP<VectorBase<Scalar> > b = createMember(fwdOp->range());
00174   V_S(b.ptr(), ST::one());
00175   const RCP<VectorBase<Scalar> > x = createMember(fwdOp->domain());
00176 
00177   // B) Print out the specialized SolveCriteria object
00178 
00179   out << "\nsolveCriteria:\n" << solveCriteria;
00180   
00181   // ToDo: Fill in the rest of the fields!
00182 
00183   // C) Solve the system with the given SolveCriteria object
00184 
00185   const int convergenceTestFrequency = 10;
00186 
00187   const RCP<ParameterList> pl = Teuchos::getParametersFromXmlString(
00188     "<ParameterList name=\"Belos\">"
00189     "  <Parameter name=\"Solver Type\" type=\"string\" value=\"Pseudo Block GMRES\"/>"
00190     "  <Parameter name=\"Convergence Test Frequency\" type=\"int\" value=\""+toString(convergenceTestFrequency)+"\"/>"
00191     "  <ParameterList name=\"Solver Types\">"
00192     "    <ParameterList name=\"Pseudo Block GMRES\">"
00193     "      <Parameter name=\"Block Size\" type=\"int\" value=\"1\"/>"
00194     "      <Parameter name=\"Convergence Tolerance\" type=\"double\" value=\"1e-13\"/>"
00195     "      <Parameter name=\"Output Frequency\" type=\"int\" value=\""+toString(convergenceTestFrequency)+"\"/>"
00196     "      <Parameter name=\"Show Maximum Residual Norm Only\" type=\"bool\" value=\"1\"/>"
00197     "      <Parameter name=\"Maximum Iterations\" type=\"int\" value=\"400\"/>"
00198     "      <Parameter name=\"Verbosity\" type=\"int\" value=\"1\"/>"
00199     "    </ParameterList>"
00200     "  </ParameterList>"
00201     "</ParameterList>"
00202     );
00203   out << "\n\npl:\n" << *pl;
00204 
00205   Thyra::BelosLinearOpWithSolveFactory<Scalar> lowsFactory;
00206   lowsFactory.setParameterList(pl);
00207   lowsFactory.setOStream(rcpFromRef(out));
00208   //lowsFactory.setVerbLevel(Teuchos::VERB_MEDIUM);
00209   lowsFactory.setVerbLevel(Teuchos::VERB_HIGH);
00210 
00211   // NOTE: To get Belos ouptut to be quite, turn down the Belos "Verbosity"
00212   // option above.  To get just the StatusTest VerboseObject output, turn up
00213   // lowsFactory output level.
00214 
00215 
00216   const RCP<LinearOpWithSolveBase<Scalar> > lows = linearOpWithSolve<Scalar>(
00217     lowsFactory, fwdOp);
00218 
00219   V_S(x.ptr(), ST::zero());
00220   SolveStatus<Scalar> solveStatus = solve<Scalar>(*lows, NOTRANS, *b, x.ptr(),
00221     optInArg(solveCriteria));
00222   out << "\nsolveStatus:\n" << solveStatus;
00223 
00224   TEST_COMPARE( solveStatus.achievedTol, <=, solveCriteria.requestedTol );
00225 
00226   // D) Compute the actual residual and return x and r
00227   
00228   const RCP<VectorBase<Scalar> > r = b->clone_v();
00229   fwdOp->apply(NOTRANS, *x, r.ptr(), ST::one(), -ST::one());
00230 
00231   *x_out = x;
00232   *r_out = r;
00233 
00234 }
00235   
00236 
00237 
00238 //
00239 // GeneralSolveCriteriaBelosStatusTest Unit Tests
00240 //
00241 
00242 
00243 TEUCHOS_UNIT_TEST( GeneralSolveCriteriaBelosStatusTest, norm_inf_r_over_norm_inf_r0 )
00244 {
00245   
00246   using Teuchos::outArg;
00247 
00248   typedef double Scalar;
00249   typedef ScalarTraits<Scalar> ST;
00250   typedef ST::magnitudeType ScalarMag;
00251 
00252   SolveCriteria<Scalar> solveCriteria;
00253   solveCriteria.solveMeasureType.numerator = SOLVE_MEASURE_NORM_RESIDUAL;
00254   solveCriteria.numeratorReductionFunc = createMockNormReductionFunctional<Scalar>();
00255   solveCriteria.solveMeasureType.denominator = SOLVE_MEASURE_NORM_SOLUTION;
00256   solveCriteria.denominatorReductionFunc = createMockMaxNormInfEpsReductionFunctional<Scalar>();
00257   solveCriteria.requestedTol = 0.9;
00258 
00259   RCP<const VectorBase<Scalar> > x, r;
00260   runGeneralSolveCriteriaBelosStatusTestCase(solveCriteria, outArg(x), outArg(r),
00261     success, out);
00262 
00263   out << "\nChecking convergence ...\n\n";
00264   
00265   const ScalarMag r_nrm_inf = norm_inf(*r);
00266   const ScalarMag x_nrm_inf = norm_inf(*x);
00267   
00268   out << "||r||inf = " << r_nrm_inf << "\n";
00269   out << "||x||inf = " << x_nrm_inf << "\n";
00270   
00271   TEST_COMPARE( r_nrm_inf / x_nrm_inf, <=, solveCriteria.requestedTol );
00272 
00273 }
00274 
00275 
00276 TEUCHOS_UNIT_TEST( GeneralSolveCriteriaBelosStatusTest, norm_inf_r_over_1 )
00277 {
00278   
00279   using Teuchos::outArg;
00280 
00281   typedef double Scalar;
00282   typedef ScalarTraits<Scalar> ST;
00283   typedef ST::magnitudeType ScalarMag;
00284 
00285   SolveCriteria<Scalar> solveCriteria;
00286   solveCriteria.solveMeasureType.numerator = SOLVE_MEASURE_NORM_RESIDUAL;
00287   solveCriteria.numeratorReductionFunc = createMockNormReductionFunctional<Scalar>();
00288   solveCriteria.solveMeasureType.denominator = SOLVE_MEASURE_ONE;
00289   solveCriteria.requestedTol = 0.9;
00290 
00291   RCP<const VectorBase<Scalar> > x, r;
00292   runGeneralSolveCriteriaBelosStatusTestCase(solveCriteria, outArg(x), outArg(r),
00293     success, out);
00294 
00295   out << "\nChecking convergence ...\n\n";
00296   
00297   const ScalarMag r_nrm_inf = norm_inf(*r);
00298   const ScalarMag x_nrm_inf = norm_inf(*x);
00299   
00300   out << "||r||inf = " << r_nrm_inf << "\n";
00301   out << "||x||inf = " << x_nrm_inf << "\n";
00302   
00303   TEST_COMPARE( r_nrm_inf, <=, solveCriteria.requestedTol );
00304 
00305 }
00306 
00307 
00308 
00309 } // namespace Thyra
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines