38#ifndef QCD_PSEUDOFERMION_EXACT_ONE_FLAVOUR_RATIO_H
39#define QCD_PSEUDOFERMION_EXACT_ONE_FLAVOUR_RATIO_H
64 SchurRedBlackDiagMooeeSolve<FermionField>
SolverHBL;
65 SchurRedBlackDiagMooeeSolve<FermionField>
SolverHBR;
66 SchurRedBlackDiagMooeeSolve<FermionField>
SolverL;
67 SchurRedBlackDiagMooeeSolve<FermionField>
SolverR;
114 Phi(_Lop.FermionGrid()),
122 std::cout <<
GridLogMessage <<
"Generating degree " <<
param.degree <<
" for x^(-1/2)" << std::endl;
129 virtual std::string
action_name() {
return "ExactOneFlavourRatioPseudoFermionAction"; }
132 std::stringstream sstream;
139 return sstream.str();
143 void spProj(
const FermionField& in, FermionField& out,
int sign,
int Ls)
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); } }
154 RealD scale = std::sqrt(0.5);
156 FermionField eta (
Lop.FermionGrid());
157 gaussian(pRNG,eta); eta = eta * scale;
169 void refresh(
const GaugeField &
U,
const FermionField &eta) {
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());
179 std::vector<FermionField> prev_solns;
193 Lop.Omega(tmp[0], tmp[1], -1, 0);
194 G5R5(CG_src, tmp[1]);
196 for(
int k=0; k<
param.degree; ++k){
200 Lop.Mdag(CG_src, Forecast_src);
203 prev_solns.push_back(CG_soln);
208 Lop.Dtilde(CG_soln, tmp[0]);
209 tmp[1] = tmp[1] + (
PowerNegHalf.residues[k]*gamma_l*gamma_l*
Lop.k ) * tmp[0];
211 Lop.Omega(tmp[1], tmp[0], -1, 1);
219 Rop.Omega(tmp[0], tmp[1], 1, 0);
220 G5R5(CG_src, tmp[1]);
223 for(
int k=0; k<
param.degree; ++k){
227 Rop.Mdag(CG_src, Forecast_src);
230 prev_solns.push_back(CG_soln);
235 Rop.Dtilde(CG_soln, tmp[0]);
236 tmp[1] = tmp[1] - (
PowerNegHalf.residues[k]*gamma_l*gamma_l*
Rop.k ) * tmp[0];
238 Rop.Omega(tmp[1], tmp[0], 1, 1);
258 void Meofa(
const GaugeField&
U,
const FermionField &in, FermionField & out)
263 FermionField spProj_in(
Lop.FermionGrid());
264 std::vector<FermionField> tmp(2,
Lop.FermionGrid());
269 Lop.Omega(spProj_in, tmp[0], -1, 0);
270 G5R5(tmp[1], tmp[0]);
273 Lop.Dtilde(tmp[0], tmp[1]);
274 Lop.Omega(tmp[1], tmp[0], -1, 1);
277 out = out -
Lop.k * tmp[1];
282 Rop.Omega(spProj_in, tmp[0], 1, 0);
283 G5R5(tmp[1], tmp[0]);
286 Rop.Dtilde(tmp[0], tmp[1]);
287 Rop.Omega(tmp[1], tmp[0], 1, 1);
290 out = out +
Rop.k * tmp[1];
296 void MeofaInv(
const GaugeField &
U,
const FermionField &in, FermionField &out) {
300 FermionField CG_src (
Lop.FermionGrid());
301 FermionField CG_soln (
Lop.FermionGrid());
302 std::vector<FermionField> tmp(2,
Lop.FermionGrid());
312 Lop.Omega(tmp[0], tmp[1], -1, 0);
313 G5R5(CG_src, tmp[1]);
320 Lop.Dtilde(CG_soln, tmp[0]);
321 tmp[1] =
Lop.k * tmp[0];
323 Lop.Omega(tmp[1], tmp[0], -1, 1);
331 Rop.Omega(tmp[0], tmp[1], 1, 0);
332 G5R5(CG_src, tmp[1]);
339 Rop.Dtilde(CG_soln, tmp[0]);
340 tmp[1] = -
Rop.k * tmp[0];
342 Rop.Omega(tmp[1], tmp[0], 1, 1);
360 FermionField spProj_Phi(
Lop.FermionGrid());
361 std::vector<FermionField> tmp(2,
Lop.FermionGrid());
368 Lop.Omega(spProj_Phi, tmp[0], -1, 0);
369 G5R5(tmp[1], tmp[0]);
372 Lop.Dtilde(tmp[0], tmp[1]);
373 Lop.Omega(tmp[1], tmp[0], -1, 1);
379 Rop.Omega(spProj_Phi, tmp[0], 1, 0);
380 G5R5(tmp[1], tmp[0]);
383 Rop.Dtilde(tmp[0], tmp[1]);
384 Rop.Omega(tmp[1], tmp[0], 1, 1);
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;
403 assert( ( test <
param.BoundsCheckTol ) &&
" Initial action check failed" );
411 virtual void deriv(
const GaugeField&
U, GaugeField& dSdU)
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());
422 GaugeField force(
Lop.GaugeGrid());
432 Lop.Omega(spProj_Phi, Omega_spProj_Phi, -1, 0);
433 G5R5(CG_src, Omega_spProj_Phi);
436 Lop.Dtilde(spProj_Phi, Chi);
437 G5R5(g5_R5_Chi, Chi);
439 dSdU = -
Lop.k * force;
444 Rop.Omega(spProj_Phi, Omega_spProj_Phi, 1, 0);
445 G5R5(CG_src, Omega_spProj_Phi);
448 Rop.Dtilde(spProj_Phi, Chi);
449 G5R5(g5_R5_Chi, Chi);
451 dSdU = dSdU +
Rop.k * force;
455 template<
class ImplD,
class ImplF>
467 virtual std::string
action_name() {
return "ExactOneFlavourRatioMixedPrecHeatbathPseudoFermionAction"; }
485 LopF(_LopF),
RopF(_RopF),
ExactOneFlavourRatioPseudoFermionAction<ImplD>(_LopD, _RopD, HeatbathCGL, HeatbathCGR, ActionCGL, ActionCGR, DerivCGL, DerivCGR, p, use_fc){}
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)
static constexpr int DaggerNo
static INTERNAL_PRECISION U
virtual void RefreshShiftCoefficients(RealD new_shift)=0
Base class for all actions.
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)
AbstractEOFAFermion< ImplF > & LopF
virtual void heatbathRefreshShiftCoefficients(int LorR, RealD to)
OneFlavourRationalParams Params
AbstractEOFAFermion< ImplF > & RopF
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)
INHERIT_IMPL_TYPES(ImplD)
MultiShiftFunction PowerNegHalf
bool use_heatbath_forecasting
SchurRedBlackDiagMooeeSolve< FermionField > SolverHBL
void refresh(const GaugeField &U, const FermionField &eta)
AbstractEOFAFermion< Impl > & Rop
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)
AbstractEOFAFermion< Impl > & Lop
virtual void heatbathRefreshShiftCoefficients(int LorR, RealD to)
virtual std::string action_name()
Report the name of the action.
OneFlavourRationalParams Params
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
const FermionField & getPhi() const
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