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,
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();
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;
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);
87 Vp_StV( r.ptr(), -alpha, *q );
RCP< const LinearOpBase< Scalar > > zero(const RCP< const VectorSpaceBase< Scalar > > &range, const RCP< const VectorSpaceBase< Scalar > > &domain)
Create a zero linear operator with given range and domain spaces.
Base class for all linear operators.
void apply(const LinearOpBase< Scalar > &M, const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha=static_cast< Scalar >(1.0), const Scalar beta=static_cast< Scalar >(0.0))
Non-member function call for M.apply(...).
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
void Vp_V(const Ptr< MultiVectorBase< Scalar > > &Z, const MultiVectorBase< Scalar > &X)
Z(i,j) += X(i,j), i = 0...Z->range()->dim()-1, j = 0...Z->domain()->dim()-1.
Abstract interface for finite-dimensional dense vectors.
void Vp_StV(const Ptr< VectorBase< Scalar > > &y, const Scalar &alpha, const VectorBase< Scalar > &x)
AXPY: y(i) = alpha * x(i) + y(i), i = 0...y->space()->dim()-1.
Scalar inner(const VectorBase< Scalar > &x, const VectorBase< Scalar > &y)
Inner/Scalar product result = <x,y>.
void V_V(const Ptr< VectorBase< Scalar > > &y, const VectorBase< Scalar > &x)
y(i) = x(i), i = 0...y->space()->dim()-1.
Teuchos::ScalarTraits< Scalar >::magnitudeType norm(const VectorBase< Scalar > &v)
Natural norm: result = sqrt(<v,v>).
Abstract interface for objects that represent a space for vectors.
RCP< VectorBase< Scalar > > createMember(const RCP< const VectorSpaceBase< Scalar > > &vs, const std::string &label="")
Create a vector member from the vector space.
#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
Type for the dimension of a vector space. `**/ typedef Teuchos::Ordinal Ordinal;.
TypeTo as(const TypeFrom &t)