00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00047 template<class Scalar>
00048 bool sillyCgSolve(
00049 const Thyra::LinearOpBase<Scalar> &A
00050 ,const Thyra::VectorBase<Scalar> &b
00051 ,const int maxNumIters
00052 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType tolerance
00053 ,Thyra::VectorBase<Scalar> *x
00054 ,std::ostream *out = NULL
00055 )
00056 {
00057
00058 typedef Teuchos::ScalarTraits<Scalar> ST; typedef typename ST::magnitudeType ScalarMag;
00059 const Scalar one = ST::one(), zero = ST::zero(); using Thyra::NOTRANS;
00060 typedef Teuchos::RefCountPtr<const Thyra::VectorSpaceBase<Scalar> > VectorSpacePtr;
00061 typedef Teuchos::RefCountPtr<Thyra::VectorBase<Scalar> > VectorPtr;
00062
00063 TEST_FOR_EXCEPT(x==NULL);
00064 THYRA_ASSERT_LINEAR_OP_VEC_APPLY_SPACES("sillyCgSolve()",A,Thyra::NOTRANS,*x,&b);
00065 Teuchos::EVerbosityLevel vl = Teuchos::VERB_MEDIUM;
00066 if(out) *out << "\nStarting CG solver ...\n" << std::scientific << "\ndescribe A:\n"<<describe(A,vl)
00067 << "\ndescribe b:\n"<<describe(b,vl)<<"\ndescribe x:\n"<<describe(*x,vl)<<"\n";
00068
00069 VectorSpacePtr space = A.domain();
00070 VectorPtr r = createMember(space);
00071 V_V(&*r,b); apply(A,NOTRANS,*x,&*r,Scalar(-one),one);
00072 const ScalarMag r0_nrm = norm(*r);
00073 if(r0_nrm==zero) return true;
00074 VectorPtr p = createMember(space), q = createMember(space);
00075 Scalar rho_old;
00076
00077 for( int iter = 0; iter <= maxNumIters; ++iter ) {
00078
00079 const ScalarMag r_nrm = norm(*r);
00080 const bool isConverged = r_nrm/r0_nrm <= tolerance;
00081 if( iter%(maxNumIters/10+1) == 0 || iter == maxNumIters || isConverged ) {
00082 if(out) *out << "Iter = " << iter << ", ||b-A*x||/||b-A*x0|| = " << (r_nrm/r0_nrm) << std::endl;
00083 if( r_nrm/r0_nrm < tolerance ) return true;
00084 }
00085
00086 const Scalar rho = scalarProd(*r,*r);
00087 if(iter==0) V_V(&*p,*r);
00088 else Vp_V( &*p, *r, Scalar(rho/rho_old) );
00089 apply(A,NOTRANS,*p,&*q);
00090 const Scalar alpha = rho/scalarProd(*p,*q);
00091 Vp_StV( x, Scalar(+alpha), *p );
00092 Vp_StV( &*r, Scalar(-alpha), *q );
00093 rho_old = rho;
00094 }
00095 return false;
00096 }
00097
00098 #endif // THYRA_SILLY_CG_SOLVE_HPP