Grid 0.7.0
MADWF.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/MADWF.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#pragma once
29
31
32template <class Fieldi, class Fieldo,IfNotSame<Fieldi,Fieldo> X=0>
33inline void convert(const Fieldi &from,Fieldo &to)
34{
35 precisionChange(to,from);
36}
37template <class Fieldi, class Fieldo,IfSame<Fieldi,Fieldo> X=0>
38inline void convert(const Fieldi &from,Fieldo &to)
39{
40 to=from;
41}
42
44 virtual void operator()(const RealD current_resid){}
46};
47
48template<class Matrixo,class Matrixi,class PVinverter,class SchurSolver, class Guesser>
49class MADWF
50{
51 private:
52 typedef typename Matrixo::FermionField FermionFieldo;
53 typedef typename Matrixi::FermionField FermionFieldi;
54
55 PVinverter & PauliVillarsSolvero;// For the outer field
56 SchurSolver & SchurSolveri; // For the inner approx field
57 Guesser & Guesseri; // To deflate the inner approx solves
58
59 Matrixo & Mato; // Action object for outer
60 Matrixi & Mati; // Action object for inner
61
64
65 //operator() is called on "callback" at the end of every inner iteration. This allows for example the adjustment of the inner
66 //tolerance to speed up subsequent iteration
68
69 public:
70 MADWF(Matrixo &_Mato,
71 Matrixi &_Mati,
72 PVinverter &_PauliVillarsSolvero,
73 SchurSolver &_SchurSolveri,
74 Guesser & _Guesseri,
75 RealD resid,
76 int _maxiter,
77 MADWFinnerIterCallbackBase* _callback = NULL) :
78
79 Mato(_Mato),Mati(_Mati),
80 SchurSolveri(_SchurSolveri),
81 PauliVillarsSolvero(_PauliVillarsSolvero),Guesseri(_Guesseri),
82 callback(_callback)
83 {
84 target_resid=resid;
85 maxiter =_maxiter;
86 };
87
89 {
90 std::cout << GridLogMessage<< " ************************************************" << std::endl;
91 std::cout << GridLogMessage<< " MADWF-like algorithm " << std::endl;
92 std::cout << GridLogMessage<< " ************************************************" << std::endl;
93
94 FermionFieldi c0i(Mati.GaugeGrid()); // 4d
95 FermionFieldi y0i(Mati.GaugeGrid()); // 4d
96 FermionFieldo c0 (Mato.GaugeGrid()); // 4d
97 FermionFieldo y0 (Mato.GaugeGrid()); // 4d
98
99 FermionFieldo A(Mato.FermionGrid()); // Temporary outer
100 FermionFieldo B(Mato.FermionGrid()); // Temporary outer
101 FermionFieldo b(Mato.FermionGrid()); // 5d source
102
103 FermionFieldo c(Mato.FermionGrid()); // PVinv source; reused so store
104 FermionFieldo defect(Mato.FermionGrid()); // 5d source
105
106 FermionFieldi ci(Mati.FermionGrid());
107 FermionFieldi yi(Mati.FermionGrid());
108 FermionFieldi xi(Mati.FermionGrid());
109 FermionFieldi srci(Mati.FermionGrid());
110 FermionFieldi Ai(Mati.FermionGrid());
111
112 RealD m=Mati.Mass();
113
115 //Import source, include Dminus factors
117 GridBase *src_grid = src.Grid();
118
119 assert( (src_grid == Mato.GaugeGrid()) || (src_grid == Mato.FermionGrid()));
120
121 if ( src_grid == Mato.GaugeGrid() ) {
122 Mato.ImportPhysicalFermionSource(src,b);
123 } else {
124 b=src;
125 }
126 std::cout << GridLogMessage << " src " <<norm2(src)<<std::endl;
127 std::cout << GridLogMessage << " b " <<norm2(b)<<std::endl;
128
129 defect = b;
130 sol5=Zero();
131 for (int i=0;i<maxiter;i++) {
132
134 // Set up c0 from current defect
136 PauliVillarsSolvero(Mato,defect,A);
137 Mato.Pdag(A,c);
138 ExtractSlice(c0, c, 0 , 0);
139
141 // Solve the inner system with surface term c0
143 ci = Zero();
144 convert(c0,c0i); // Possible precison change
145 InsertSlice(c0i,ci,0, 0);
146
147 // Dwm P y = Dwm x = D(1) P (c0,0,0,0)^T
148 Mati.P(ci,Ai);
149 Mati.SetMass(1.0); Mati.M(Ai,srci); Mati.SetMass(m);
150 SchurSolveri(Mati,srci,xi,Guesseri);
151 Mati.Pdag(xi,yi);
152 ExtractSlice(y0i, yi, 0 , 0);
153 convert(y0i,y0); // Possible precision change
154
156 // Propagate solution back to outer system
157 // Build Pdag PV^-1 Dm P [-sol4,c2,c3... cL]
159 c0 = - y0;
160 InsertSlice(c0, c, 0 , 0);
161
163 // Reconstruct the bulk solution Pdag PV^-1 Dm P
165 Mato.P(c,B);
166 Mato.M(B,A);
168 Mato.Pdag(B,A);
169
171 // Reinsert surface prop
173 InsertSlice(y0,A,0,0);
174
176 // Convert from y back to x
178 Mato.P(A,B);
179
180 // sol5' = sol5 + M^-1 defect
181 // = sol5 + M^-1 src - M^-1 M sol5 ...
182 sol5 = sol5 + B;
183 std::cout << GridLogMessage << "***************************************" <<std::endl;
184 std::cout << GridLogMessage << " Sol5 update "<<std::endl;
185 std::cout << GridLogMessage << "***************************************" <<std::endl;
186 std::cout << GridLogMessage << " Sol5 now "<<norm2(sol5)<<std::endl;
187 std::cout << GridLogMessage << " delta "<<norm2(B)<<std::endl;
188
189 // New defect = b - M sol5
190 Mato.M(sol5,A);
191 defect = b - A;
192
193 std::cout << GridLogMessage << " defect "<<norm2(defect)<<std::endl;
194
195 double resid = ::sqrt(norm2(defect) / norm2(b));
196 std::cout << GridLogMessage << "Residual " << i << ": " << resid << std::endl;
197 std::cout << GridLogMessage << "***************************************" <<std::endl;
198
199 if(callback != NULL) (*callback)(resid);
200
201 if (resid < target_resid) {
202 return;
203 }
204 }
205
206 std::cout << GridLogMessage << "MADWF : Exceeded maxiter "<<std::endl;
207 assert(0);
208
209 }
210
211};
212
accelerator_inline Grid_simd< S, V > sqrt(const Grid_simd< S, V > &r)
B
RealD norm2(const Lattice< vobj > &arg)
void InsertSlice(const Lattice< vobj > &lowDim, Lattice< vobj > &higherDim, int slice, int orthog)
void ExtractSlice(Lattice< vobj > &lowDim, const Lattice< vobj > &higherDim, int slice, int orthog)
void precisionChange(Lattice< VobjOut > &out, const Lattice< VobjIn > &in, const precisionChangeWorkspace &workspace)
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
void convert(const Fieldi &from, Fieldo &to)
Definition MADWF.h:33
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
double RealD
Definition Simd.h:61
RealD target_resid
Definition MADWF.h:62
int maxiter
Definition MADWF.h:63
Matrixo::FermionField FermionFieldo
Definition MADWF.h:52
Guesser & Guesseri
Definition MADWF.h:57
Matrixo & Mato
Definition MADWF.h:59
Matrixi & Mati
Definition MADWF.h:60
void operator()(const FermionFieldo &src, FermionFieldo &sol5)
Definition MADWF.h:88
MADWF(Matrixo &_Mato, Matrixi &_Mati, PVinverter &_PauliVillarsSolvero, SchurSolver &_SchurSolveri, Guesser &_Guesseri, RealD resid, int _maxiter, MADWFinnerIterCallbackBase *_callback=NULL)
Definition MADWF.h:70
SchurSolver & SchurSolveri
Definition MADWF.h:56
Matrixi::FermionField FermionFieldi
Definition MADWF.h:53
MADWFinnerIterCallbackBase * callback
Definition MADWF.h:67
PVinverter & PauliVillarsSolvero
Definition MADWF.h:55
Definition Simd.h:194
virtual ~MADWFinnerIterCallbackBase()
Definition MADWF.h:45
virtual void operator()(const RealD current_resid)
Definition MADWF.h:44