10#ifndef THYRA_SILLY_CG_SOLVE_HPP
11#define THYRA_SILLY_CG_SOLVE_HPP
13#include "Thyra_LinearOpBase.hpp"
14#include "Thyra_VectorStdOps.hpp"
15#include "Thyra_AssertOp.hpp"
33 const int maxNumIters,
42 const Scalar one = ST::one(), zero = ST::zero();
using Teuchos::as;
51 std::ios::fmtflags fmt(out.flags());
53 out <<
"\nStarting CG solver ...\n" << std::scientific <<
"\ndescribe A:\n"<<describe(A, vl)
54 <<
"\ndescribe b:\n"<<describe(b, vl)<<
"\ndescribe x:\n"<<describe(*x, vl)<<
"\n";
57 const RCP<const VectorSpaceBase<Scalar> > space = A.
domain();
58 const RCP<VectorBase<Scalar> > r = createMember(space);
60 V_V(r.ptr(), b); apply<Scalar>(A, NOTRANS, *x, r.ptr(), -one, one);
61 const ScalarMag r0_nrm = norm(*r);
62 if (r0_nrm==zero)
return true;
63 const RCP<VectorBase<Scalar> > p = createMember(space), q = createMember(space);
64 Scalar rho_old = -one;
67 for(
int iter = 0; iter <= maxNumIters; ++iter ) {
70 const ScalarMag r_nrm = norm(*r);
71 const bool isConverged = r_nrm/r0_nrm <= tolerance;
72 if( iter%(maxNumIters/10+1) == 0 || iter == maxNumIters || isConverged ) {
73 out <<
"Iter = " << iter <<
", ||b-A*x||/||b-A*x0|| = " << (r_nrm/r0_nrm) << std::endl;
74 if( r_nrm/r0_nrm < tolerance ) {
81 const Scalar rho = inner(*r, *r);
82 if (iter==0) V_V(p.ptr(), *r);
83 else Vp_V( p.ptr(), *r, rho/rho_old );
84 apply<Scalar>(A, NOTRANS, *p, q.ptr());
85 const Scalar alpha = rho/inner(*p, *q);
86 Vp_StV( x, +alpha, *p );
87 Vp_StV( r.ptr(), -alpha, *q );
Base class for all linear operators.
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
Abstract interface for finite-dimensional dense vectors.
Abstract interface for objects that represent a space for vectors.
#define THYRA_ASSERT_LINEAR_OP_VEC_APPLY_SPACES(FUNC_NAME, M, M_T, X, Y)
This is a very useful macro that should be used to validate that the spaces for the vector version of...
@ NOTRANS
Use the non-transposed operator.
TypeTo as(const TypeFrom &t)