Grid 0.7.0
PrecGeneralisedConjugateResidual.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/PrecGeneralisedConjugateResidual.h
6
7 Copyright (C) 2015
8
9Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
10Author: Peter Boyle <paboyle@ph.ed.ac.uk>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License along
23 with this program; if not, write to the Free Software Foundation, Inc.,
24 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25
26 See the full license in the file "LICENSE" in the top level distribution directory
27*************************************************************************************/
28/* END LEGAL */
29#ifndef GRID_PREC_GCR_H
30#define GRID_PREC_GCR_H
31
33//VPGCR Abe and Zhang, 2005.
34//INTERNATIONAL JOURNAL OF NUMERICAL ANALYSIS AND MODELING
35//Computing and Information Volume 2, Number 2, Pages 147-161
36//NB. Likely not original reference since they are focussing on a preconditioner variant.
37// but VPGCR was nicely written up in their paper
40
41#define GCRLogLevel std::cout << GridLogMessage <<std::string(level,'\t')<< " Level "<<level<<" "
42
43template<class Field>
45public:
46 using LinearFunction<Field>::operator();
50 int mmax;
51 int nstep;
52 int steps;
53 int level;
57
60
61 void Level(int lv) { level=lv; };
62
64 Tolerance(tol),
65 MaxIterations(maxit),
66 Linop(_Linop),
67 Preconditioner(Prec),
68 mmax(_mmax),
69 nstep(_nstep)
70 {
71 level=1;
72 verbose=1;
73 };
74
75 void operator() (const Field &src, Field &psi){
76
77 psi=Zero();
78 RealD cp, ssq,rsq;
79 ssq=norm2(src);
80 rsq=Tolerance*Tolerance*ssq;
81
82 Field r(src.Grid());
83
84 PrecTimer.Reset();
85 MatTimer.Reset();
86 LinalgTimer.Reset();
87
88 GridStopWatch SolverTimer;
89 SolverTimer.Start();
90
91 steps=0;
92 for(int k=0;k<MaxIterations;k++){
93
94 cp=GCRnStep(src,psi,rsq);
95
96 GCRLogLevel <<"PGCR("<<mmax<<","<<nstep<<") "<< steps <<" steps cp = "<<cp<<" target "<<rsq <<std::endl;
97
98 if(cp<rsq) {
99
100 SolverTimer.Stop();
101
102 Linop.HermOp(psi,r);
103 axpy(r,-1.0,src,r);
104 RealD tr = norm2(r);
105 GCRLogLevel<<"PGCR: Converged on iteration " <<steps
106 << " computed residual "<<sqrt(cp/ssq)
107 << " true residual " <<sqrt(tr/ssq)
108 << " target " <<Tolerance <<std::endl;
109
110 GCRLogLevel<<"PGCR Time elapsed: Total "<< SolverTimer.Elapsed() <<std::endl;
111 /*
112 GCRLogLevel<<"PGCR Time elapsed: Precon "<< PrecTimer.Elapsed() <<std::endl;
113 GCRLogLevel<<"PGCR Time elapsed: Matrix "<< MatTimer.Elapsed() <<std::endl;
114 GCRLogLevel<<"PGCR Time elapsed: Linalg "<< LinalgTimer.Elapsed() <<std::endl;
115 */
116 return;
117 }
118
119 }
120 GCRLogLevel<<"Variable Preconditioned GCR did not converge"<<std::endl;
121 // assert(0);
122 }
123
124 RealD GCRnStep(const Field &src, Field &psi,RealD rsq){
125
126 RealD cp;
127 RealD a, b;
128 RealD zAz, zAAz;
129 RealD rq;
130
131 GridBase *grid = src.Grid();
132
133 Field r(grid);
134 Field z(grid);
135 Field tmp(grid);
136 Field ttmp(grid);
137 Field Az(grid);
138
140 // history for flexible orthog
142 std::vector<Field> q(mmax,grid);
143 std::vector<Field> p(mmax,grid);
144 std::vector<RealD> qq(mmax);
145
146 GCRLogLevel<< "PGCR nStep("<<nstep<<")"<<std::endl;
147
149 // initial guess x0 is taken as nonzero.
150 // r0=src-A x0 = src
152 MatTimer.Start();
153 Linop.HermOpAndNorm(psi,Az,zAz,zAAz);
154 MatTimer.Stop();
155
156
157 LinalgTimer.Start();
158 r=src-Az;
159 LinalgTimer.Stop();
160 GCRLogLevel<< "PGCR true residual r = src - A psi "<<norm2(r) <<std::endl;
161
163 // p = Prec(r)
165
166 PrecTimer.Start();
167 Preconditioner(r,z);
168 PrecTimer.Stop();
169
170 MatTimer.Start();
171 Linop.HermOpAndNorm(z,Az,zAz,zAAz);
172 MatTimer.Stop();
173
174 LinalgTimer.Start();
175
176 //p[0],q[0],qq[0]
177 p[0]= z;
178 q[0]= Az;
179 qq[0]= zAAz;
180
181 cp =norm2(r);
182 LinalgTimer.Stop();
183
184 for(int k=0;k<nstep;k++){
185
186 steps++;
187
188 int kp = k+1;
189 int peri_k = k %mmax;
190 int peri_kp= kp%mmax;
191
192 LinalgTimer.Start();
193 rq= real(innerProduct(r,q[peri_k])); // what if rAr not real?
194 a = rq/qq[peri_k];
195
196 axpy(psi,a,p[peri_k],psi);
197
198 cp = axpy_norm(r,-a,q[peri_k],r);
199 LinalgTimer.Stop();
200
201 GCRLogLevel<< "PGCR step["<<steps<<"] resid " << cp << " target " <<rsq<<std::endl;
202
203 if((k==nstep-1)||(cp<rsq)){
204 return cp;
205 }
206
207
208 PrecTimer.Start();
209 Preconditioner(r,z);// solve Az = r
210 PrecTimer.Stop();
211
212 MatTimer.Start();
213 Linop.HermOpAndNorm(z,Az,zAz,zAAz);
214 MatTimer.Stop();
215
216 LinalgTimer.Start();
217
218 q[peri_kp]=Az;
219 p[peri_kp]=z;
220
221 int northog = ((kp)>(mmax-1))?(mmax-1):(kp); // if more than mmax done, we orthog all mmax history.
222 for(int back=0;back<northog;back++){
223
224 int peri_back=(k-back)%mmax; assert((k-back)>=0);
225
226 b=-real(innerProduct(q[peri_back],Az))/qq[peri_back];
227 p[peri_kp]=p[peri_kp]+b*p[peri_back];
228 q[peri_kp]=q[peri_kp]+b*q[peri_back];
229
230 }
231 qq[peri_kp]=norm2(q[peri_kp]); // could use axpy_norm
232 LinalgTimer.Stop();
233 }
234 assert(0); // never reached
235 return cp;
236 }
237};
239#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)
#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
void Start(void)
Definition Timer.h:92
GridTime Elapsed(void) const
Definition Timer.h:113
void Stop(void)
Definition Timer.h:99
PrecGeneralisedConjugateResidual(RealD tol, Integer maxit, LinearOperatorBase< Field > &_Linop, LinearFunction< Field > &Prec, int _mmax, int _nstep)
RealD GCRnStep(const Field &src, Field &psi, RealD rsq)
void operator()(const Field &src, Field &psi)
Definition Simd.h:194