Grid 0.7.0
PrecConjugateResidual.h
Go to the documentation of this file.
1/*************************************************************************************
2
3 Grid physics library, www.github.com/paboyle/Grid
4
5 Source file: ./lib/algorithms/iterative/PrecConjugateResidual.h
6
7 Copyright (C) 2015
8
9Author: Peter Boyle <paboyle@ph.ed.ac.uk>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License along
22 with this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25 See the full license in the file "LICENSE" in the top level distribution directory
26*************************************************************************************/
27/* END LEGAL */
28#ifndef GRID_PREC_CONJUGATE_RESIDUAL_H
29#define GRID_PREC_CONJUGATE_RESIDUAL_H
30
32
34// Base classes for iterative processes based on operators
35// single input vec, single output vec.
37
38template<class Field>
40public:
45
50
51 void operator() (LinearOperatorBase<Field> &Linop,const Field &src, Field &psi){
52
53 RealD a, b, c, d;
54 RealD cp, ssq,rsq;
55
56 RealD rAr, rAAr, rArp;
57 RealD pAp, pAAp;
58
59 GridBase *grid = src.Grid();
60 Field r(grid), p(grid), Ap(grid), Ar(grid), z(grid);
61
62 psi=zero;
63 r = src;
64 Preconditioner(r,p);
65
66
67
68 Linop.HermOpAndNorm(p,Ap,pAp,pAAp);
69 Ar=Ap;
70 rAr=pAp;
71 rAAr=pAAp;
72
73 cp =norm2(r);
74 ssq=norm2(src);
75 rsq=Tolerance*Tolerance*ssq;
76
77 if (verbose) std::cout<<GridLogMessage<<"PrecConjugateResidual: iteration " <<0<<" residual "<<cp<< " target"<< rsq<<std::endl;
78
79 for(int k=0;k<MaxIterations;k++){
80
81
82 Preconditioner(Ap,z);
83 RealD rq= real(innerProduct(Ap,z));
84
85 a = rAr/rq;
86
87 axpy(psi,a,p,psi);
88 cp = axpy_norm(r,-a,z,r);
89
90 rArp=rAr;
91
92 Linop.HermOpAndNorm(r,Ar,rAr,rAAr);
93
94 b =rAr/rArp;
95
96 axpy(p,b,p,r);
97 pAAp=axpy_norm(Ap,b,Ap,Ar);
98
99 if(verbose) std::cout<<GridLogMessage<<"PrecConjugateResidual: iteration " <<k<<" residual "<<cp<< " target"<< rsq<<std::endl;
100
101 if(cp<rsq) {
102 Linop.HermOp(psi,Ap);
103 axpy(r,-1.0,src,Ap);
104 RealD true_resid = norm2(r)/ssq;
105 std::cout<<GridLogMessage<<"PrecConjugateResidual: Converged on iteration " <<k
106 << " computed residual "<<sqrt(cp/ssq)
107 << " true residual "<<sqrt(true_resid)
108 << " target " <<Tolerance <<std::endl;
109 return;
110 }
111
112 }
113
114 std::cout<<GridLogMessage<<"PrecConjugateResidual did NOT converge"<<std::endl;
115 assert(0);
116 }
117};
119#endif
accelerator_inline Grid_simd< S, V > sqrt(const Grid_simd< S, V > &r)
RealD axpy_norm(Lattice< vobj > &ret, sobj a, const Lattice< vobj > &x, const Lattice< vobj > &y)
void axpy(Lattice< vobj > &ret, sobj a, const Lattice< vobj > &x, const Lattice< vobj > &y)
Lattice< vobj > real(const Lattice< vobj > &lhs)
ComplexD innerProduct(const Lattice< vobj > &left, const Lattice< vobj > &right)
RealD norm2(const Lattice< vobj > &arg)
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
uint32_t Integer
Definition Simd.h:58
double RealD
Definition Simd.h:61
virtual void HermOp(const Field &in, Field &out)=0
virtual void HermOpAndNorm(const Field &in, Field &out, RealD &n1, RealD &n2)=0
LinearFunction< Field > & Preconditioner
PrecConjugateResidual(RealD tol, Integer maxit, LinearFunction< Field > &Prec)
void operator()(LinearOperatorBase< Field > &Linop, const Field &src, Field &psi)