Grid 0.7.0
ContinuedFractionFermion5DImplementation.h
Go to the documentation of this file.
1/*************************************************************************************
2
3 Grid physics library, www.github.com/paboyle/Grid
4
5 Source file: ./lib/qcd/action/fermion/ContinuedFractionFermion5D.cc
6
7 Copyright (C) 2015
8
9Author: Peter Boyle <pabobyle@ph.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 */
31
32#pragma once
33
35
36template<class Impl>
37void ContinuedFractionFermion5D<Impl>::SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD scale)
38{
39 SetCoefficientsZolotarev(1.0/scale,zdata);
40}
41template<class Impl>
42void ContinuedFractionFermion5D<Impl>::SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolotarev_data *zdata)
43{
44 // How to check Ls matches??
45 std::cout<<GridLogMessage << zdata->n << " - n"<<std::endl;
46 std::cout<<GridLogMessage << zdata->da << " -da "<<std::endl;
47 std::cout<<GridLogMessage << zdata->db << " -db"<<std::endl;
48 std::cout<<GridLogMessage << zdata->dn << " -dn"<<std::endl;
49 std::cout<<GridLogMessage << zdata->dd << " -dd"<<std::endl;
50 int Ls = this->Ls;
51 std::cout<<GridLogMessage << Ls << " Ls"<<std::endl;
52 assert(zdata->db==Ls);// Beta has Ls coeffs
54 R=(1+this->mass)/(1-this->mass);
55
56 Beta.resize(Ls);
57 cc.resize(Ls);
58 cc_d.resize(Ls);
59 sqrt_cc.resize(Ls);
60 for(int i=0; i < Ls ; i++){
61 Beta[i] = zdata -> beta[i];
62 cc[i] = 1.0/Beta[i];
63 cc_d[i]=std::sqrt(cc[i]);
64 }
65
66 cc_d[Ls-1]=1.0;
67 for(int i=0; i < Ls-1 ; i++){
68 sqrt_cc[i]= std::sqrt(cc[i]*cc[i+1]);
69 }
70 sqrt_cc[Ls-2]=std::sqrt(cc[Ls-2]);
71
72
73 ZoloHiInv =1.0/zolo_hi;
74 dw_diag = (4.0-this->M5)*ZoloHiInv;
75
76 See.resize(Ls);
77 Aee.resize(Ls);
78 int sign=1;
79 for(int s=0;s<Ls;s++){
80 Aee[s] = sign * Beta[s] * dw_diag;
81 sign = - sign;
82 }
83 Aee[Ls-1] += R;
84
85 See[0] = Aee[0];
86 for(int s=1;s<Ls;s++){
87 See[s] = Aee[s] - 1.0/See[s-1];
88 }
89 for(int s=0;s<Ls;s++){
90 std::cout<<GridLogMessage <<"s = "<<s<<" Beta "<<Beta[s]<<" Aee "<<Aee[s] <<" See "<<See[s] <<std::endl;
91 }
92}
93
94
95
96template<class Impl>
97void ContinuedFractionFermion5D<Impl>::M (const FermionField &psi, FermionField &chi)
98{
99 int Ls = this->Ls;
100
101 FermionField D(psi.Grid());
102
103 this->DW(psi,D,DaggerNo);
104
105 int sign=1;
106 for(int s=0;s<Ls;s++){
107 if ( s==0 ) {
108 ag5xpby_ssp(chi,cc[0]*Beta[0]*sign*ZoloHiInv,D,sqrt_cc[0],psi,s,s+1); // Multiplies Dw by G5 so Hw
109 } else if ( s==(Ls-1) ){
110 RealD R=(1.0+mass)/(1.0-mass);
111 ag5xpby_ssp(chi,Beta[s]*ZoloHiInv,D,sqrt_cc[s-1],psi,s,s-1);
112 ag5xpby_ssp(chi,R,psi,1.0,chi,s,s);
113 } else {
114 ag5xpby_ssp(chi,cc[s]*Beta[s]*sign*ZoloHiInv,D,sqrt_cc[s],psi,s,s+1);
115 axpby_ssp(chi,1.0,chi,sqrt_cc[s-1],psi,s,s-1);
117 sign=-sign;
118 }
119}
120template<class Impl>
121void ContinuedFractionFermion5D<Impl>::Mdag (const FermionField &psi, FermionField &chi)
122{
123 // This matrix is already hermitian. (g5 Dw) = Dw dag g5 = (g5 Dw)dag
124 // The rest of matrix is symmetric.
125 // Can ignore "dag"
126 M(psi,chi);
127}
128template<class Impl>
129void ContinuedFractionFermion5D<Impl>::Mdir (const FermionField &psi, FermionField &chi,int dir,int disp){
130 int Ls = this->Ls;
131
132 this->DhopDir(psi,chi,dir,disp); // Dslash on diagonal. g5 Dslash is hermitian
133
134 int sign=1;
135 for(int s=0;s<Ls;s++){
136 if ( s==(Ls-1) ){
137 ag5xpby_ssp(chi,Beta[s]*ZoloHiInv,chi,0.0,chi,s,s);
138 } else {
139 ag5xpby_ssp(chi,cc[s]*Beta[s]*sign*ZoloHiInv,chi,0.0,chi,s,s);
140 }
141 sign=-sign;
142 }
143}
144template<class Impl>
145void ContinuedFractionFermion5D<Impl>::MdirAll (const FermionField &psi, std::vector<FermionField> &chi)
146{
147 int Ls = this->Ls;
148
149 this->DhopDirAll(psi,chi); // Dslash on diagonal. g5 Dslash is hermitian
150
151 for(int p=0;p<chi.size();p++){
152 int sign=1;
153 for(int s=0;s<Ls;s++){
154 if ( s==(Ls-1) ){
155 ag5xpby_ssp(chi[p],Beta[s]*ZoloHiInv,chi[p],0.0,chi[p],s,s);
156 } else {
157 ag5xpby_ssp(chi[p],cc[s]*Beta[s]*sign*ZoloHiInv,chi[p],0.0,chi[p],s,s);
158 }
159 sign=-sign;
160 }
161 }
162}
163template<class Impl>
164void ContinuedFractionFermion5D<Impl>::Meooe (const FermionField &psi, FermionField &chi)
165{
166 int Ls = this->Ls;
167
168 // Apply 4d dslash
169 if ( psi.Checkerboard() == Odd ) {
170 this->DhopEO(psi,chi,DaggerNo); // Dslash on diagonal. g5 Dslash is hermitian
171 } else {
172 this->DhopOE(psi,chi,DaggerNo); // Dslash on diagonal. g5 Dslash is hermitian
173 }
174
175 int sign=1;
176 for(int s=0;s<Ls;s++){
177 if ( s==(Ls-1) ){
178 ag5xpby_ssp(chi,Beta[s]*ZoloHiInv,chi,0.0,chi,s,s);
179 } else {
180 ag5xpby_ssp(chi,cc[s]*Beta[s]*sign*ZoloHiInv,chi,0.0,chi,s,s);
181 }
182 sign=-sign;
183 }
184}
185template<class Impl>
186void ContinuedFractionFermion5D<Impl>::MeooeDag (const FermionField &psi, FermionField &chi)
187{
188 this->Meooe(psi,chi);
189}
190template<class Impl>
191void ContinuedFractionFermion5D<Impl>::Mooee (const FermionField &psi, FermionField &chi)
192{
193 int Ls = this->Ls;
194
195 int sign=1;
196 for(int s=0;s<Ls;s++){
197 if ( s==0 ) {
198 ag5xpby_ssp(chi,cc[0]*Beta[0]*sign*dw_diag,psi,sqrt_cc[0],psi,s,s+1); // Multiplies Dw by G5 so Hw
199 } else if ( s==(Ls-1) ){
200 // Drop the CC here.
201 double R=(1+mass)/(1-mass);
202 ag5xpby_ssp(chi,Beta[s]*dw_diag,psi,sqrt_cc[s-1],psi,s,s-1);
203 ag5xpby_ssp(chi,R,psi,1.0,chi,s,s);
204 } else {
205 ag5xpby_ssp(chi,cc[s]*Beta[s]*sign*dw_diag,psi,sqrt_cc[s],psi,s,s+1);
206 axpby_ssp(chi,1.0,chi,sqrt_cc[s-1],psi,s,s-1);
207 }
208 sign=-sign;
209 }
210}
211
212template<class Impl>
213void ContinuedFractionFermion5D<Impl>::MooeeDag (const FermionField &psi, FermionField &chi)
214{
215 this->Mooee(psi,chi);
216}
217template<class Impl>
218void ContinuedFractionFermion5D<Impl>::MooeeInv (const FermionField &psi, FermionField &chi)
219{
220 int Ls = this->Ls;
221
222 // Apply Linv
223 axpby_ssp(chi,1.0/cc_d[0],psi,0.0,psi,0,0);
224 for(int s=1;s<Ls;s++){
225 axpbg5y_ssp(chi,1.0/cc_d[s],psi,-1.0/See[s-1],chi,s,s-1);
226 }
227 // Apply Dinv
228 for(int s=0;s<Ls;s++){
229 ag5xpby_ssp(chi,1.0/See[s],chi,0.0,chi,s,s); //only appearance of See[0]
230 }
231 // Apply Uinv = (Linv)^T
232 axpby_ssp(chi,1.0/cc_d[Ls-1],chi,0.0,chi,Ls-1,Ls-1);
233 for(int s=Ls-2;s>=0;s--){
234 axpbg5y_ssp(chi,1.0/cc_d[s],chi,-1.0*cc_d[s+1]/See[s]/cc_d[s],chi,s,s+1);
235 }
236}
237template<class Impl>
238void ContinuedFractionFermion5D<Impl>::MooeeInvDag (const FermionField &psi, FermionField &chi)
239{
240 this->MooeeInv(psi,chi);
241}
242
243// force terms; five routines; default to Dhop on diagonal
244template<class Impl>
245void ContinuedFractionFermion5D<Impl>::MDeriv (GaugeField &mat,const FermionField &U,const FermionField &V,int dag)
246{
247 int Ls = this->Ls;
248
249 FermionField D(V.Grid());
250
251 int sign=1;
252 for(int s=0;s<Ls;s++){
253 if ( s==(Ls-1) ){
254 ag5xpby_ssp(D,Beta[s]*ZoloHiInv,U,0.0,U,s,s);
255 } else {
256 ag5xpby_ssp(D,cc[s]*Beta[s]*sign*ZoloHiInv,U,0.0,U,s,s);
257 }
258 sign=-sign;
259 }
260 this->DhopDeriv(mat,D,V,DaggerNo);
261};
262template<class Impl>
263void ContinuedFractionFermion5D<Impl>::MoeDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag)
264{
265 int Ls = this->Ls;
266
267 FermionField D(V.Grid());
268
269 int sign=1;
270 for(int s=0;s<Ls;s++){
271 if ( s==(Ls-1) ){
272 ag5xpby_ssp(D,Beta[s]*ZoloHiInv,U,0.0,U,s,s);
273 } else {
274 ag5xpby_ssp(D,cc[s]*Beta[s]*sign*ZoloHiInv,U,0.0,U,s,s);
275 }
276 sign=-sign;
277 }
278 this->DhopDerivOE(mat,D,V,DaggerNo);
279};
280template<class Impl>
281void ContinuedFractionFermion5D<Impl>::MeoDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag)
282{
283 int Ls = this->Ls;
284
285 FermionField D(V.Grid());
286
287 int sign=1;
288 for(int s=0;s<Ls;s++){
289 if ( s==(Ls-1) ){
290 ag5xpby_ssp(D,Beta[s]*ZoloHiInv,U,0.0,U,s,s);
291 } else {
292 ag5xpby_ssp(D,cc[s]*Beta[s]*sign*ZoloHiInv,U,0.0,U,s,s);
293 }
294 sign=-sign;
295 }
296 this->DhopDerivEO(mat,D,V,DaggerNo);
297};
298
299// Constructors
300template<class Impl>
302 GaugeField &_Umu,
303 GridCartesian &FiveDimGrid,
304 GridRedBlackCartesian &FiveDimRedBlackGrid,
305 GridCartesian &FourDimGrid,
306 GridRedBlackCartesian &FourDimRedBlackGrid,
307 RealD _mass,RealD M5,const ImplParams &p) :
308 WilsonFermion5D<Impl>(_Umu,
309 FiveDimGrid, FiveDimRedBlackGrid,
310 FourDimGrid, FourDimRedBlackGrid,M5,p),
311 mass(_mass)
312{
313 int Ls = this->Ls;
314 assert((Ls&0x1)==1); // Odd Ls required
315}
316
317 template<class Impl>
318 void ContinuedFractionFermion5D<Impl>::ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d)
319 {
320 int Ls = this->Ls;
321 conformable(solution5d.Grid(),this->FermionGrid());
322 conformable(exported4d.Grid(),this->GaugeGrid());
323 ExtractSlice(exported4d, solution5d, Ls-1, 0);
324 }
325 template<class Impl>
326 void ContinuedFractionFermion5D<Impl>::ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d)
327 {
328 int Ls = this->Ls;
329 conformable(imported5d.Grid(),this->FermionGrid());
330 conformable(input4d.Grid() ,this->GaugeGrid());
331 FermionField tmp(this->FermionGrid());
332 tmp=Zero();
333 InsertSlice(input4d, tmp, Ls-1, 0);
334 tmp=Gamma(Gamma::Algebra::Gamma5)*tmp;
335 this->Dminus(tmp,imported5d);
336 }
337
338
static const int Odd
void conformable(const Lattice< obj1 > &lhs, const Lattice< obj2 > &rhs)
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 ag5xpby_ssp(Lattice< vobj > &z, Coeff a, const Lattice< vobj > &x, Coeff b, const Lattice< vobj > &y, int s, int sp)
Definition LinalgUtils.h:80
void axpby_ssp(Lattice< vobj > &z, Coeff a, const Lattice< vobj > &x, Coeff b, const Lattice< vobj > &y, int s, int sp)
Definition LinalgUtils.h:59
void axpbg5y_ssp(Lattice< vobj > &z, Coeff a, const Lattice< vobj > &x, Coeff b, const Lattice< vobj > &y, int s, int sp)
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
static constexpr int DaggerNo
Definition QCD.h:69
double RealD
Definition Simd.h:61
static INTERNAL_PRECISION U
Definition Zolotarev.cc:230
virtual void Mdir(const FermionField &in, FermionField &out, int dir, int disp)
virtual void Meooe(const FermionField &in, FermionField &out)
virtual void MdirAll(const FermionField &in, std::vector< FermionField > &out)
virtual void MeoDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
virtual void M(const FermionField &in, FermionField &out)
virtual void MooeeInvDag(const FermionField &in, FermionField &out)
virtual void Mooee(const FermionField &in, FermionField &out)
virtual void Mdag(const FermionField &in, FermionField &out)
virtual void ImportPhysicalFermionSource(const FermionField &input4d, FermionField &imported5d)
void SetCoefficientsZolotarev(RealD zolo_hi, Approx::zolotarev_data *zdata)
virtual void MoeDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
virtual void MooeeDag(const FermionField &in, FermionField &out)
virtual void ExportPhysicalFermionSolution(const FermionField &solution5d, FermionField &exported4d)
void SetCoefficientsTanh(Approx::zolotarev_data *zdata, RealD scale)
ContinuedFractionFermion5D(GaugeField &_Umu, GridCartesian &FiveDimGrid, GridRedBlackCartesian &FiveDimRedBlackGrid, GridCartesian &FourDimGrid, GridRedBlackCartesian &FourDimRedBlackGrid, RealD _mass, RealD M5, const ImplParams &p=ImplParams())
virtual void MeooeDag(const FermionField &in, FermionField &out)
virtual void MDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
virtual void MooeeInv(const FermionField &in, FermionField &out)
virtual void Dminus(const FermionField &psi, FermionField &chi)
Definition Gamma.h:10
FermionField & tmp(void)
GridBase * FermionGrid(void)
virtual void DhopDerivEO(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
void DW(const FermionField &in, FermionField &out, int dag)
void DhopDir(const FermionField &in, FermionField &out, int dir, int disp)
void DhopDirAll(const FermionField &in, std::vector< FermionField > &out)
WilsonFermion5D(GaugeField &_Umu, GridCartesian &FiveDimGrid, GridRedBlackCartesian &FiveDimRedBlackGrid, GridCartesian &FourDimGrid, GridRedBlackCartesian &FourDimRedBlackGrid, double _M5, const ImplParams &p=ImplParams())
virtual void DhopDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
void DhopEO(const FermionField &in, FermionField &out, int dag)
virtual void DhopDerivOE(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
void DhopOE(const FermionField &in, FermionField &out, int dag)
Definition Simd.h:194