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
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
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
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
00074 const RCP<const VectorSpaceBase<Scalar> > space = A.domain();
00075 const RCP<VectorBase<Scalar> > r = createMember(space);
00076
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
00084 for( int iter = 0; iter <= maxNumIters; ++iter ) {
00085
00086
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;
00092 }
00093
00094
00095 const Scalar rho = inner(*r, *r);
00096 if (iter==0) V_V(p.ptr(), *r);
00097 else Vp_V( p.ptr(), *r, rho/rho_old );
00098 apply<Scalar>(A, NOTRANS, *p, q.ptr());
00099 const Scalar alpha = rho/inner(*p, *q);
00100 Vp_StV( x, +alpha, *p );
00101 Vp_StV( r.ptr(), -alpha, *q );
00102 rho_old = rho;
00103
00104 }
00105
00106 return false;
00107
00108 }
00109
00110 #endif // THYRA_SILLY_CG_SOLVE_HPP