Grid 0.7.0
ExactOneFlavourRatio.h
Go to the documentation of this file.
1/*************************************************************************************
2
3Grid physics library, www.github.com/paboyle/Grid
4
5Source file: ./lib/qcd/action/pseudofermion/ExactOneFlavourRatio.h
6
7Copyright (C) 2017
8
9Author: Peter Boyle <paboyle@ph.ed.ac.uk>
10Author: David Murphy <dmurphy@phys.columbia.edu>
11
12This program is free software; you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation; either version 2 of the License, or
15(at your option) any later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License along
23with this program; if not, write to the Free Software Foundation, Inc.,
2451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25
26See the full license in the file "LICENSE" in the top level distribution directory
27*************************************************************************************/
28/* END LEGAL */
29
31// Implementation of exact one flavour algorithm (EOFA) //
32// using fermion classes defined in: //
33// Grid/qcd/action/fermion/DomainWallEOFAFermion.h (Shamir) //
34// Grid/qcd/action/fermion/MobiusEOFAFermion.h (Mobius) //
35// arXiv: 1403.1683, 1706.05843 //
37
38#ifndef QCD_PSEUDOFERMION_EXACT_ONE_FLAVOUR_RATIO_H
39#define QCD_PSEUDOFERMION_EXACT_ONE_FLAVOUR_RATIO_H
40
42
44 // Exact one flavour implementation of DWF determinant ratio //
46
47 //Note: using mixed prec CG for the heatbath solver in this action class will not work
48 // because the L, R operators must have their shift coefficients updated throughout the heatbath step
49 // You will find that the heatbath solver simply won't converge.
50 // To use mixed precision here use the ExactOneFlavourRatioMixedPrecHeatbathPseudoFermionAction variant below
51 template<class Impl>
52 class ExactOneFlavourRatioPseudoFermionAction : public Action<typename Impl::GaugeField>
53 {
54 public:
59
60 private:
62 AbstractEOFAFermion<Impl>& Lop; // the basic LH operator
63 AbstractEOFAFermion<Impl>& Rop; // the basic RH operator
64 SchurRedBlackDiagMooeeSolve<FermionField> SolverHBL;
65 SchurRedBlackDiagMooeeSolve<FermionField> SolverHBR;
66 SchurRedBlackDiagMooeeSolve<FermionField> SolverL;
67 SchurRedBlackDiagMooeeSolve<FermionField> SolverR;
68 SchurRedBlackDiagMooeeSolve<FermionField> DerivativeSolverL;
69 SchurRedBlackDiagMooeeSolve<FermionField> DerivativeSolverR;
70 FermionField Phi; // the pseudofermion field for this trajectory
71
72 RealD norm2_eta; //|eta|^2 where eta is the random gaussian field used to generate the pseudofermion field
73 bool initial_action; //true for the first call to S after refresh, for which the identity S = |eta|^2 holds provided the rational approx is good
74 public:
75
76 //Used in the heatbath, refresh the shift coefficients of the L (LorR=0) or R (LorR=1) operator
77 virtual void heatbathRefreshShiftCoefficients(int LorR, RealD to){
78 AbstractEOFAFermion<Impl>&op = LorR == 0 ? Lop : Rop;
80 }
81
82
83 //Use the same solver for L,R in all cases
90
91 //Use the same solver for L,R in the heatbath but different solvers elsewhere
97 Params& p,
98 bool use_fc=false)
99 : ExactOneFlavourRatioPseudoFermionAction(_Lop,_Rop,HeatbathCG,HeatbathCG, ActionCGL, ActionCGR, DerivCGL,DerivCGR,p,use_fc) {};
100
101 //Use different solvers for L,R in all cases
107 Params& p,
108 bool use_fc=false) :
109 Lop(_Lop),
110 Rop(_Rop),
111 SolverHBL(HeatbathCGL,false,true), SolverHBR(HeatbathCGR,false,true),
112 SolverL(ActionCGL, false, true), SolverR(ActionCGR, false, true),
113 DerivativeSolverL(DerivCGL, false, true), DerivativeSolverR(DerivCGR, false, true),
114 Phi(_Lop.FermionGrid()),
115 param(p),
117 initial_action(false)
118 {
119 AlgRemez remez(param.lo, param.hi, param.precision);
120
121 // MdagM^(+- 1/2)
122 std::cout << GridLogMessage << "Generating degree " << param.degree << " for x^(-1/2)" << std::endl;
123 remez.generateApprox(param.degree, 1, 2);
124 PowerNegHalf.Init(remez, param.tolerance, true);
125 };
126
127 const FermionField &getPhi() const{ return Phi; }
128
129 virtual std::string action_name() { return "ExactOneFlavourRatioPseudoFermionAction"; }
130
131 virtual std::string LogParameters() {
132 std::stringstream sstream;
133 sstream << GridLogMessage << "[" << action_name() << "] Low :" << param.lo << std::endl;
134 sstream << GridLogMessage << "[" << action_name() << "] High :" << param.hi << std::endl;
135 sstream << GridLogMessage << "[" << action_name() << "] Max iterations :" << param.MaxIter << std::endl;
136 sstream << GridLogMessage << "[" << action_name() << "] Tolerance :" << param.tolerance << std::endl;
137 sstream << GridLogMessage << "[" << action_name() << "] Degree :" << param.degree << std::endl;
138 sstream << GridLogMessage << "[" << action_name() << "] Precision :" << param.precision << std::endl;
139 return sstream.str();
140 }
141
142 // Spin projection
143 void spProj(const FermionField& in, FermionField& out, int sign, int Ls)
144 {
145 if(sign == 1){ for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(out, 0.0, in, 1.0, in, s, s); } }
146 else{ for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(out, 0.0, in, 1.0, in, s, s); } }
147 }
148
149 virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG& pRNG) {
150 // P(eta_o) = e^{- eta_o^dag eta_o}
151 //
152 // e^{x^2/2 sig^2} => sig^2 = 0.5.
153 //
154 RealD scale = std::sqrt(0.5);
155
156 FermionField eta (Lop.FermionGrid());
157 gaussian(pRNG,eta); eta = eta * scale;
158
159 refresh(U,eta);
160 }
161
162 // EOFA heatbath: see Eqn. (29) of arXiv:1706.05843
163 // We generate a Gaussian noise vector \eta, and then compute
164 // \Phi = M_{\rm EOFA}^{-1/2} * \eta
165 // using a rational approximation to the inverse square root
166 //
167 // As a check of rational require \Phi^dag M_{EOFA} \Phi == eta^dag M^-1/2^dag M M^-1/2 eta = eta^dag eta
168 //
169 void refresh(const GaugeField &U, const FermionField &eta) {
170 Lop.ImportGauge(U);
171 Rop.ImportGauge(U);
172
173 FermionField CG_src (Lop.FermionGrid());
174 FermionField CG_soln (Lop.FermionGrid());
175 FermionField Forecast_src(Lop.FermionGrid());
176 std::vector<FermionField> tmp(2, Lop.FermionGrid());
177
178 // Use chronological inverter to forecast solutions across poles
179 std::vector<FermionField> prev_solns;
180 if(use_heatbath_forecasting){ prev_solns.reserve(param.degree); }
182
183 // \Phi = ( \alpha_{0} + \sum_{k=1}^{N_{p}} \alpha_{l} * \gamma_{l} ) * \eta
184 RealD N(PowerNegHalf.norm);
185 for(int k=0; k<param.degree; ++k){ N += PowerNegHalf.residues[k] / ( 1.0 + PowerNegHalf.poles[k] ); }
186 Phi = eta * N;
187
188 // LH terms:
189 // \Phi = \Phi + k \sum_{k=1}^{N_{p}} P_{-} \Omega_{-}^{\dagger} ( H(mf)
190 // - \gamma_{l} \Delta_{-}(mf,mb) P_{-} )^{-1} \Omega_{-} P_{-} \eta
191 RealD gamma_l(0.0);
192 spProj(eta, tmp[0], -1, Lop.Ls);
193 Lop.Omega(tmp[0], tmp[1], -1, 0);
194 G5R5(CG_src, tmp[1]);
195 tmp[1] = Zero();
196 for(int k=0; k<param.degree; ++k){
197 gamma_l = 1.0 / ( 1.0 + PowerNegHalf.poles[k] );
199 if(use_heatbath_forecasting){ // Forecast CG guess using solutions from previous poles
200 Lop.Mdag(CG_src, Forecast_src);
201 CG_soln = Forecast(Lop, Forecast_src, prev_solns);
202 SolverHBL(Lop, CG_src, CG_soln);
203 prev_solns.push_back(CG_soln);
204 } else {
205 CG_soln = Zero(); // Just use zero as the initial guess
206 SolverHBL(Lop, CG_src, CG_soln);
207 }
208 Lop.Dtilde(CG_soln, tmp[0]); // We actually solved Cayley preconditioned system: transform back
209 tmp[1] = tmp[1] + ( PowerNegHalf.residues[k]*gamma_l*gamma_l*Lop.k ) * tmp[0];
210 }
211 Lop.Omega(tmp[1], tmp[0], -1, 1);
212 spProj(tmp[0], tmp[1], -1, Lop.Ls);
213 Phi = Phi + tmp[1];
214
215 // RH terms:
216 // \Phi = \Phi - k \sum_{k=1}^{N_{p}} P_{+} \Omega_{+}^{\dagger} ( H(mb)
217 // + \gamma_{l} \Delta_{+}(mf,mb) P_{+} )^{-1} \Omega_{+} P_{+} \eta
218 spProj(eta, tmp[0], 1, Rop.Ls);
219 Rop.Omega(tmp[0], tmp[1], 1, 0);
220 G5R5(CG_src, tmp[1]);
221 tmp[1] = Zero();
222 if(use_heatbath_forecasting){ prev_solns.clear(); } // empirically, LH solns don't help for RH solves
223 for(int k=0; k<param.degree; ++k){
224 gamma_l = 1.0 / ( 1.0 + PowerNegHalf.poles[k] );
227 Rop.Mdag(CG_src, Forecast_src);
228 CG_soln = Forecast(Rop, Forecast_src, prev_solns);
229 SolverHBR(Rop, CG_src, CG_soln);
230 prev_solns.push_back(CG_soln);
231 } else {
232 CG_soln = Zero();
233 SolverHBR(Rop, CG_src, CG_soln);
234 }
235 Rop.Dtilde(CG_soln, tmp[0]); // We actually solved Cayley preconditioned system: transform back
236 tmp[1] = tmp[1] - ( PowerNegHalf.residues[k]*gamma_l*gamma_l*Rop.k ) * tmp[0];
237 }
238 Rop.Omega(tmp[1], tmp[0], 1, 1);
239 spProj(tmp[0], tmp[1], 1, Rop.Ls);
240 Phi = Phi + tmp[1];
241
242 // Reset shift coefficients for energy and force evals
245
246 //Mark that the next call to S is the first after refresh
247 initial_action = true;
248
249
250 // Bounds check
251 RealD EtaDagEta = norm2(eta);
252 norm2_eta = EtaDagEta;
253
254 // RealD PhiDagMPhi= norm2(eta);
255
256 };
257
258 void Meofa(const GaugeField& U,const FermionField &in, FermionField & out)
259 {
260 Lop.ImportGauge(U);
261 Rop.ImportGauge(U);
262
263 FermionField spProj_in(Lop.FermionGrid());
264 std::vector<FermionField> tmp(2, Lop.FermionGrid());
265 out = in;
266
267 // LH term: S = S - k <\Phi| P_{-} \Omega_{-}^{\dagger} H(mf)^{-1} \Omega_{-} P_{-} |\Phi>
268 spProj(in, spProj_in, -1, Lop.Ls);
269 Lop.Omega(spProj_in, tmp[0], -1, 0);
270 G5R5(tmp[1], tmp[0]);
271 tmp[0] = Zero();
272 SolverL(Lop, tmp[1], tmp[0]);
273 Lop.Dtilde(tmp[0], tmp[1]); // We actually solved Cayley preconditioned system: transform back
274 Lop.Omega(tmp[1], tmp[0], -1, 1);
275 spProj(tmp[0], tmp[1], -1, Lop.Ls);
276
277 out = out - Lop.k * tmp[1];
278
279 // RH term: S = S + k <\Phi| P_{+} \Omega_{+}^{\dagger} ( H(mb)
280 // - \Delta_{+}(mf,mb) P_{+} )^{-1} \Omega_{+} P_{+} |\Phi>
281 spProj(in, spProj_in, 1, Rop.Ls);
282 Rop.Omega(spProj_in, tmp[0], 1, 0);
283 G5R5(tmp[1], tmp[0]);
284 tmp[0] = Zero();
285 SolverR(Rop, tmp[1], tmp[0]);
286 Rop.Dtilde(tmp[0], tmp[1]);
287 Rop.Omega(tmp[1], tmp[0], 1, 1);
288 spProj(tmp[0], tmp[1], 1, Rop.Ls);
289
290 out = out + Rop.k * tmp[1];
291 }
292
293 //Due to the structure of EOFA, it is no more expensive to compute the inverse of Meofa
294 //To ensure correctness we can simply reuse the heatbath code but use the rational approx
295 //f(x) = 1/x which corresponds to alpha_0=0, alpha_1=1, beta_1=0 => gamma_1=1
296 void MeofaInv(const GaugeField &U, const FermionField &in, FermionField &out) {
297 Lop.ImportGauge(U);
298 Rop.ImportGauge(U);
299
300 FermionField CG_src (Lop.FermionGrid());
301 FermionField CG_soln (Lop.FermionGrid());
302 std::vector<FermionField> tmp(2, Lop.FermionGrid());
303
304 // \Phi = ( \alpha_{0} + \sum_{k=1}^{N_{p}} \alpha_{l} * \gamma_{l} ) * \eta
305 // = 1 * \eta
306 out = in;
307
308 // LH terms:
309 // \Phi = \Phi + k \sum_{k=1}^{N_{p}} P_{-} \Omega_{-}^{\dagger} ( H(mf)
310 // - \gamma_{l} \Delta_{-}(mf,mb) P_{-} )^{-1} \Omega_{-} P_{-} \eta
311 spProj(in, tmp[0], -1, Lop.Ls);
312 Lop.Omega(tmp[0], tmp[1], -1, 0);
313 G5R5(CG_src, tmp[1]);
314 {
315 heatbathRefreshShiftCoefficients(0, -1.); //-gamma_1 = -1.
316
317 CG_soln = Zero(); // Just use zero as the initial guess
318 SolverHBL(Lop, CG_src, CG_soln);
319
320 Lop.Dtilde(CG_soln, tmp[0]); // We actually solved Cayley preconditioned system: transform back
321 tmp[1] = Lop.k * tmp[0];
322 }
323 Lop.Omega(tmp[1], tmp[0], -1, 1);
324 spProj(tmp[0], tmp[1], -1, Lop.Ls);
325 out = out + tmp[1];
326
327 // RH terms:
328 // \Phi = \Phi - k \sum_{k=1}^{N_{p}} P_{+} \Omega_{+}^{\dagger} ( H(mb)
329 // - \beta_l\gamma_{l} \Delta_{+}(mf,mb) P_{+} )^{-1} \Omega_{+} P_{+} \eta
330 spProj(in, tmp[0], 1, Rop.Ls);
331 Rop.Omega(tmp[0], tmp[1], 1, 0);
332 G5R5(CG_src, tmp[1]);
333 {
334 heatbathRefreshShiftCoefficients(1, 0.); //-gamma_1 * beta_1 = 0
335
336 CG_soln = Zero();
337 SolverHBR(Rop, CG_src, CG_soln);
338
339 Rop.Dtilde(CG_soln, tmp[0]); // We actually solved Cayley preconditioned system: transform back
340 tmp[1] = - Rop.k * tmp[0];
341 }
342 Rop.Omega(tmp[1], tmp[0], 1, 1);
343 spProj(tmp[0], tmp[1], 1, Rop.Ls);
344 out = out + tmp[1];
345
346 // Reset shift coefficients for energy and force evals
349 };
350
351
352
353
354 // EOFA action: see Eqn. (10) of arXiv:1706.05843
355 virtual RealD S(const GaugeField& U)
356 {
357 Lop.ImportGauge(U);
358 Rop.ImportGauge(U);
359
360 FermionField spProj_Phi(Lop.FermionGrid());
361 std::vector<FermionField> tmp(2, Lop.FermionGrid());
362
363 // S = <\Phi|\Phi>
364 RealD action(norm2(Phi));
365
366 // LH term: S = S - k <\Phi| P_{-} \Omega_{-}^{\dagger} H(mf)^{-1} \Omega_{-} P_{-} |\Phi>
367 spProj(Phi, spProj_Phi, -1, Lop.Ls);
368 Lop.Omega(spProj_Phi, tmp[0], -1, 0);
369 G5R5(tmp[1], tmp[0]);
370 tmp[0] = Zero();
371 SolverL(Lop, tmp[1], tmp[0]);
372 Lop.Dtilde(tmp[0], tmp[1]); // We actually solved Cayley preconditioned system: transform back
373 Lop.Omega(tmp[1], tmp[0], -1, 1);
374 action -= Lop.k * innerProduct(spProj_Phi, tmp[0]).real();
375
376 // RH term: S = S + k <\Phi| P_{+} \Omega_{+}^{\dagger} ( H(mb)
377 // - \Delta_{+}(mf,mb) P_{+} )^{-1} \Omega_{+} P_{+} |\Phi>
378 spProj(Phi, spProj_Phi, 1, Rop.Ls);
379 Rop.Omega(spProj_Phi, tmp[0], 1, 0);
380 G5R5(tmp[1], tmp[0]);
381 tmp[0] = Zero();
382 SolverR(Rop, tmp[1], tmp[0]);
383 Rop.Dtilde(tmp[0], tmp[1]);
384 Rop.Omega(tmp[1], tmp[0], 1, 1);
385 action += Rop.k * innerProduct(spProj_Phi, tmp[0]).real();
386
387 if(initial_action){
388 //For the first call to S after refresh, S = |eta|^2. We can use this to ensure the rational approx is good
389 RealD diff = action - norm2_eta;
390
391 //S_init = eta^dag M^{-1/2} M M^{-1/2} eta
392 //S_init - eta^dag eta = eta^dag ( M^{-1/2} M M^{-1/2} - 1 ) eta
393
394 //If approximate solution
395 //S_init - eta^dag eta = eta^dag ( [M^{-1/2}+\delta M^{-1/2}] M [M^{-1/2}+\delta M^{-1/2}] - 1 ) eta
396 // \approx eta^dag ( \delta M^{-1/2} M^{1/2} + M^{1/2}\delta M^{-1/2} ) eta
397 // We divide out |eta|^2 to remove source scaling but the tolerance on this check should still be somewhat higher than the actual approx tolerance
398 RealD test = fabs(diff)/norm2_eta; //test the quality of the rational approx
399
400 std::cout << GridLogMessage << action_name() << " initial action " << action << " expect " << norm2_eta << "; diff " << diff << std::endl;
401 std::cout << GridLogMessage << action_name() << "[ eta^dag ( M^{-1/2} M M^{-1/2} - 1 ) eta ]/|eta^2| = " << test << " expect 0 (tol " << param.BoundsCheckTol << ")" << std::endl;
402
403 assert( ( test < param.BoundsCheckTol ) && " Initial action check failed" );
404 initial_action = false;
405 }
406
407 return action;
408 };
409
410 // EOFA pseudofermion force: see Eqns. (34)-(36) of arXiv:1706.05843
411 virtual void deriv(const GaugeField& U, GaugeField& dSdU)
412 {
413 Lop.ImportGauge(U);
414 Rop.ImportGauge(U);
415
416 FermionField spProj_Phi (Lop.FermionGrid());
417 FermionField Omega_spProj_Phi(Lop.FermionGrid());
418 FermionField CG_src (Lop.FermionGrid());
419 FermionField Chi (Lop.FermionGrid());
420 FermionField g5_R5_Chi (Lop.FermionGrid());
421
422 GaugeField force(Lop.GaugeGrid());
423
425 // PAB:
426 // Optional single precision derivative ?
428
429 // LH: dSdU = k \chi_{L}^{\dagger} \gamma_{5} R_{5} ( \partial_{x,\mu} D_{w} ) \chi_{L}
430 // \chi_{L} = H(mf)^{-1} \Omega_{-} P_{-} \Phi
431 spProj(Phi, spProj_Phi, -1, Lop.Ls);
432 Lop.Omega(spProj_Phi, Omega_spProj_Phi, -1, 0);
433 G5R5(CG_src, Omega_spProj_Phi);
434 spProj_Phi = Zero();
435 DerivativeSolverL(Lop, CG_src, spProj_Phi);
436 Lop.Dtilde(spProj_Phi, Chi);
437 G5R5(g5_R5_Chi, Chi);
438 Lop.MDeriv(force, g5_R5_Chi, Chi, DaggerNo);
439 dSdU = -Lop.k * force;
440
441 // RH: dSdU = dSdU - k \chi_{R}^{\dagger} \gamma_{5} R_{5} ( \partial_{x,\mu} D_{w} ) \chi_{}
442 // \chi_{R} = ( H(mb) - \Delta_{+}(mf,mb) P_{+} )^{-1} \Omega_{+} P_{+} \Phi
443 spProj(Phi, spProj_Phi, 1, Rop.Ls);
444 Rop.Omega(spProj_Phi, Omega_spProj_Phi, 1, 0);
445 G5R5(CG_src, Omega_spProj_Phi);
446 spProj_Phi = Zero();
447 DerivativeSolverR(Rop, CG_src, spProj_Phi);
448 Rop.Dtilde(spProj_Phi, Chi);
449 G5R5(g5_R5_Chi, Chi);
450 Lop.MDeriv(force, g5_R5_Chi, Chi, DaggerNo);
451 dSdU = dSdU + Rop.k * force;
452 };
453 };
454
455 template<class ImplD, class ImplF>
457 public:
460
461 private:
462 AbstractEOFAFermion<ImplF>& LopF; // the basic LH operator
463 AbstractEOFAFermion<ImplF>& RopF; // the basic RH operator
464
465 public:
466
467 virtual std::string action_name() { return "ExactOneFlavourRatioMixedPrecHeatbathPseudoFermionAction"; }
468
469 //Used in the heatbath, refresh the shift coefficients of the L (LorR=0) or R (LorR=1) operator
475
483 Params& p,
484 bool use_fc=false) :
485 LopF(_LopF), RopF(_RopF), ExactOneFlavourRatioPseudoFermionAction<ImplD>(_LopD, _RopD, HeatbathCGL, HeatbathCGR, ActionCGL, ActionCGR, DerivCGL, DerivCGR, p, use_fc){}
486 };
487
488
490
491#endif
ComplexD innerProduct(const Lattice< vobj > &left, const Lattice< vobj > &right)
RealD norm2(const Lattice< vobj > &arg)
void gaussian(GridParallelRNG &rng, Lattice< vobj > &l)
void axpby_ssp_pplus(Lattice< vobj > &z, Coeff a, const Lattice< vobj > &x, Coeff b, const Lattice< vobj > &y, int s, int sp)
void axpby_ssp_pminus(Lattice< vobj > &z, Coeff a, const Lattice< vobj > &x, Coeff b, const Lattice< vobj > &y, int s, int sp)
void G5R5(Lattice< vobj > &z, const Lattice< vobj > &x)
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 RefreshShiftCoefficients(RealD new_shift)=0
Base class for all actions.
Definition ActionBase.h:64
double generateApprox(int num_degree, int den_degree, unsigned long power_num, unsigned long power_den, int a_len, double *a_param, int *a_pow)
Definition Remez.cc:114
virtual std::string action_name()
Report the name of the action.
ExactOneFlavourRatioMixedPrecHeatbathPseudoFermionAction(AbstractEOFAFermion< ImplF > &_LopF, AbstractEOFAFermion< ImplF > &_RopF, AbstractEOFAFermion< ImplD > &_LopD, AbstractEOFAFermion< ImplD > &_RopD, OperatorFunction< FermionField > &HeatbathCGL, OperatorFunction< FermionField > &HeatbathCGR, OperatorFunction< FermionField > &ActionCGL, OperatorFunction< FermionField > &ActionCGR, OperatorFunction< FermionField > &DerivCGL, OperatorFunction< FermionField > &DerivCGR, Params &p, bool use_fc=false)
SchurRedBlackDiagMooeeSolve< FermionField > SolverHBL
void refresh(const GaugeField &U, const FermionField &eta)
SchurRedBlackDiagMooeeSolve< FermionField > SolverL
ExactOneFlavourRatioPseudoFermionAction(AbstractEOFAFermion< Impl > &_Lop, AbstractEOFAFermion< Impl > &_Rop, OperatorFunction< FermionField > &CG, Params &p, bool use_fc=false)
void Meofa(const GaugeField &U, const FermionField &in, FermionField &out)
ExactOneFlavourRatioPseudoFermionAction(AbstractEOFAFermion< Impl > &_Lop, AbstractEOFAFermion< Impl > &_Rop, OperatorFunction< FermionField > &HeatbathCGL, OperatorFunction< FermionField > &HeatbathCGR, OperatorFunction< FermionField > &ActionCGL, OperatorFunction< FermionField > &ActionCGR, OperatorFunction< FermionField > &DerivCGL, OperatorFunction< FermionField > &DerivCGR, Params &p, bool use_fc=false)
virtual void heatbathRefreshShiftCoefficients(int LorR, RealD to)
virtual std::string action_name()
Report the name of the action.
virtual std::string LogParameters()
Print the parameters of the action.
virtual RealD S(const GaugeField &U)
Evaluate this action with the given gauge field.
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG &pRNG)
Refresh pseudofermion fields.
SchurRedBlackDiagMooeeSolve< FermionField > SolverR
SchurRedBlackDiagMooeeSolve< FermionField > DerivativeSolverR
virtual void deriv(const GaugeField &U, GaugeField &dSdU)
SchurRedBlackDiagMooeeSolve< FermionField > SolverHBR
void MeofaInv(const GaugeField &U, const FermionField &in, FermionField &out)
ExactOneFlavourRatioPseudoFermionAction(AbstractEOFAFermion< Impl > &_Lop, AbstractEOFAFermion< Impl > &_Rop, OperatorFunction< FermionField > &HeatbathCG, OperatorFunction< FermionField > &ActionCGL, OperatorFunction< FermionField > &ActionCGR, OperatorFunction< FermionField > &DerivCGL, OperatorFunction< FermionField > &DerivCGR, Params &p, bool use_fc=false)
void spProj(const FermionField &in, FermionField &out, int sign, int Ls)
SchurRedBlackDiagMooeeSolve< FermionField > DerivativeSolverL
Definition Simd.h:194