Thyra Version of the Day
Loading...
Searching...
No Matches
sillyCgSolve.hpp
1// @HEADER
2// *****************************************************************************
3// Thyra: Interfaces and Support for Abstract Numerical Algorithms
4//
5// Copyright 2004 NTESS and the Thyra contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef THYRA_SILLY_CG_SOLVE_HPP
11#define THYRA_SILLY_CG_SOLVE_HPP
12
13#include "Thyra_LinearOpBase.hpp"
14#include "Thyra_VectorStdOps.hpp"
15#include "Thyra_AssertOp.hpp"
16
17
29template<class Scalar>
30bool sillyCgSolve(
33 const int maxNumIters,
34 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType tolerance,
36 std::ostream &out
37 )
38{
39
40 // Create some typedefs and some other stuff to make the code cleaner
41 typedef Teuchos::ScalarTraits<Scalar> ST; typedef typename ST::magnitudeType ScalarMag;
42 const Scalar one = ST::one(), zero = ST::zero(); using Teuchos::as;
44 using Thyra::NOTRANS; using Thyra::V_V; using Thyra::apply;
45
46
47 // Validate input
48 THYRA_ASSERT_LINEAR_OP_VEC_APPLY_SPACES("sillyCgSolve()", A, Thyra::NOTRANS, *x, &b);
50
51 std::ios::fmtflags fmt(out.flags());
52
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";
55
56 // Initialization
57 const RCP<const VectorSpaceBase<Scalar> > space = A.domain();
58 const RCP<VectorBase<Scalar> > r = createMember(space);
59 // r = -A*x + b
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;
65
66 // Perform the iterations
67 for( int iter = 0; iter <= maxNumIters; ++iter ) {
68
69 // Check convergence and output iteration
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 ) {
75 out.flags(fmt);
76 return true; // Success!
77 }
78 }
79
80 // Compute iteration
81 const Scalar rho = inner(*r, *r); // <r,r> -> rho
82 if (iter==0) V_V(p.ptr(), *r); // r -> p (iter == 0)
83 else Vp_V( p.ptr(), *r, rho/rho_old ); // r+(rho/rho_old)*p -> p (iter > 0)
84 apply<Scalar>(A, NOTRANS, *p, q.ptr()); // A*p -> q
85 const Scalar alpha = rho/inner(*p, *q); // rho/<p,q> -> alpha
86 Vp_StV( x, +alpha, *p ); // +alpha*p + x -> x
87 Vp_StV( r.ptr(), -alpha, *q ); // -alpha*q + r -> r
88 rho_old = rho; // rho -> rho_old (for next iter)
89
90 }
91
92 out.flags(fmt);
93 return false; // Failure
94} // end sillyCgSolve
95
96#endif // THYRA_SILLY_CG_SOLVE_HPP
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)