|
Thyra Package Browser (Single Doxygen Collection) Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Thyra: Interfaces and Support for Abstract Numerical Algorithms 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 #ifndef THYRA_SILLY_CG_SOLVE_HPP 00030 #define THYRA_SILLY_CG_SOLVE_HPP 00031 00032 #include "Thyra_LinearOpBase.hpp" 00033 #include "Thyra_VectorStdOps.hpp" 00034 #include "Thyra_AssertOp.hpp" 00035 00036 00048 template<class Scalar> 00049 bool sillyCgSolve( 00050 const Thyra::LinearOpBase<Scalar> &A, 00051 const Thyra::VectorBase<Scalar> &b, 00052 const int maxNumIters, 00053 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType tolerance, 00054 const Teuchos::Ptr<Thyra::VectorBase<Scalar> > &x, 00055 std::ostream &out 00056 ) 00057 { 00058 00059 // Create some typedefs and some other stuff to make the code cleaner 00060 typedef Teuchos::ScalarTraits<Scalar> ST; typedef typename ST::magnitudeType ScalarMag; 00061 const Scalar one = ST::one(), zero = ST::zero(); using Teuchos::as; 00062 using Teuchos::RCP; using Thyra::VectorSpaceBase; using Thyra::VectorBase; 00063 using Thyra::NOTRANS; using Thyra::V_V; using Thyra::apply; 00064 00065 00066 // Validate input 00067 THYRA_ASSERT_LINEAR_OP_VEC_APPLY_SPACES("sillyCgSolve()", A, Thyra::NOTRANS, *x, &b); 00068 Teuchos::EVerbosityLevel vl = Teuchos::VERB_MEDIUM; 00069 00070 out << "\nStarting CG solver ...\n" << std::scientific << "\ndescribe A:\n"<<describe(A, vl) 00071 << "\ndescribe b:\n"<<describe(b, vl)<<"\ndescribe x:\n"<<describe(*x, vl)<<"\n"; 00072 00073 // Initialization 00074 const RCP<const VectorSpaceBase<Scalar> > space = A.domain(); 00075 const RCP<VectorBase<Scalar> > r = createMember(space); 00076 // r = -A*x + b 00077 V_V(r.ptr(), b); apply<Scalar>(A, NOTRANS, *x, r.ptr(), -one, one); 00078 const ScalarMag r0_nrm = norm(*r); 00079 if (r0_nrm==zero) return true; 00080 const RCP<VectorBase<Scalar> > p = createMember(space), q = createMember(space); 00081 Scalar rho_old = -one; 00082 00083 // Perform the iterations 00084 for( int iter = 0; iter <= maxNumIters; ++iter ) { 00085 00086 // Check convergence and output iteration 00087 const ScalarMag r_nrm = norm(*r); 00088 const bool isConverged = r_nrm/r0_nrm <= tolerance; 00089 if( iter%(maxNumIters/10+1) == 0 || iter == maxNumIters || isConverged ) { 00090 out << "Iter = " << iter << ", ||b-A*x||/||b-A*x0|| = " << (r_nrm/r0_nrm) << std::endl; 00091 if( r_nrm/r0_nrm < tolerance ) return true; // Success! 00092 } 00093 00094 // Compute iteration 00095 const Scalar rho = inner(*r, *r); // <r,r> -> rho 00096 if (iter==0) V_V(p.ptr(), *r); // r -> p (iter == 0) 00097 else Vp_V( p.ptr(), *r, rho/rho_old ); // r+(rho/rho_old)*p -> p (iter > 0) 00098 apply<Scalar>(A, NOTRANS, *p, q.ptr()); // A*p -> q 00099 const Scalar alpha = rho/inner(*p, *q); // rho/<p,q> -> alpha 00100 Vp_StV( x, +alpha, *p ); // +alpha*p + x -> x 00101 Vp_StV( r.ptr(), -alpha, *q ); // -alpha*q + r -> r 00102 rho_old = rho; // rho -> rho_old (for next iter) 00103 00104 } 00105 00106 return false; // Failure 00107 00108 } // end sillyCgSolve 00109 00110 #endif // THYRA_SILLY_CG_SOLVE_HPP
1.7.4