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