CHROMA
one_flavor_ratio_rat_rat_monomial5d_w.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 /*! @file
4  * @brief One flavor ratio of rational monomials using RHMC
5  */
6 
7 #ifndef __one_flavor_ratio_rat_rat_monomial5d_w_h__
8 #define __one_flavor_ratio_rat_rat_monomial5d_w_h__
9 
15 
16 #include <typeinfo>
17 
18 namespace Chroma
19 {
20  //-------------------------------------------------------------------------------------------
21  //! Exact 1 flavor fermact monomial in extra dimensions
22  /*! @ingroup monomial
23  *
24  * Exact 1 flavor fermact monomial. Preconditioning is not
25  * specified yet.
26  * Can supply a default dsdq and pseudoferm refresh algorithm
27  */
28  template<typename P, typename Q, typename Phi>
30  {
31  public:
32  //! virtual destructor:
34 
35  //! Compute the total action
36  virtual Double S(const AbsFieldState<P,Q>& s) = 0;
37 
38  //! Compute dsdq for the system...
39  /*! Monomial of the form chi^dag*(M^dag*M)*chi */
40  virtual void dsdq(P& F, const AbsFieldState<P,Q>& s)
41  {
42  START_CODE();
43 
44  // SelfIdentification/Encapsultaion Rule
45  XMLWriter& xml_out = TheXMLLogWriter::Instance();
46  push(xml_out, "OneFlavorRatioRatRatExactWilsonTypeFermMonomial5D");
47 
48  /**** Identical code for unprec and even-odd prec case *****/
49 
50  // S_f = chi^dag* P(V^dag*V)/Q(V^dag*V)* N(M^dag*M)/D(M^dag*M)* P(V^dag*V)/Q(V^dag*V)* chi
51  //
52  // Here, M is some 5D operator and V is the Pauli-Villars field
53  // N and D makeup the rat. poly of the M term and P and & makeup the rat.poly of the denom term
54  //
55  // Need
56  // dS_f/dU = - \sum_i psi_i^dag * n_i * [d(M^dag)*M + M^dag*dM] * psi
57  // - \sum_i psiPV_i^dag * p_i * [d(V^dag)*V + V^dag*dV] * psiPV
58  //
59  // where psi_i = (M^dag*M + n_i)^(-1)*chi
60  // and psiPV_i = (V^dag*V + p_i)^(-1)*chiPV
61  //
62  // In Balint's notation, the result is
63  // \dot{S} = -\sum_i p_i [ X_i^dag*\dot{M}^\dag*Y_i - Y_i^dag\dot{M}*X_i]
64  // where
65  // X_i = (M^dag*M + q_i)^(-1)*chi Y_i = M*X_i
66  // In Robert's notation, X_i -> psi_i .
67  //
69 
70  // Create a state for linop
72 
73  // Start the force
74  F.resize(Nd);
75  F = zero;
76 
77  // Force term for the linop
78  {
79  // Get multi-shift system solver
81 
82  // Get linear operator
84 
85  // Partial Fraction Expansion coeffs for force
86  const RemezCoeff_t& fpfe = getNumerFPFE();
87 
88  multi1d< multi1d<Phi> > X;
89  multi1d<Phi> Y;
90  P F_1, F_2, F_tmp(Nd);
91  multi1d<int> n_m_count(getNPF());
92 
93  // Loop over the pseudoferms
94  for(int n=0; n < getNPF(); ++n)
95  {
96  // The multi-shift inversion
97  SystemSolverResults_t res = (*invMdagM)(X, fpfe.pole, getPhi()[n]);
98  n_m_count[n] = res.n_count;
99 
100  // Loop over solns and accumulate force contributions
101  F_tmp = zero;
102  for(int i=0; i < X.size(); ++i)
103  {
104  (*M)(Y, X[i], PLUS);
105 
106  // The d(M^dag)*M term
107  M->deriv(F_1, X[i], Y, MINUS);
108 
109  // The M^dag*d(M) term
110  M->deriv(F_2, Y, X[i], PLUS);
111  F_1 += F_2;
112 
113  // Reweight each contribution in partial fraction
114  for(int mu=0; mu < F.size(); mu++)
115  F_tmp[mu] -= fpfe.res[i] * F_1[mu];
116  }
117 
118  // We are not monitoring by pole anymore, so I will
119  // Just accumulate this and take one derivative at the end
120  F += F_tmp; // add on base force terms
121  }
122 
123  // Take the derivative with respect to possibly fat links
124  state->deriv(F);
125 
126  // Write out the n_count array and the Forces for the Base Operator
127  write(xml_out, "n_m_count", n_m_count);
128  monitorForces(xml_out, "ForcesOperator", F);
129  }
130 
131  monitorForces(xml_out, "Forces", F);
132 
133  pop(xml_out);
134 
135  END_CODE();
136  }
137 
138 
139  //! Refresh pseudofermions
140  /*!
141  * This routine calculates the pseudofermion field (chi) for the case
142  * of rational evolution
143  *
144  * chi = n(Q)*[d(Q)]^(-1) * eta
145  * Where: Q = M^dag*M
146  * d(Q) = (Q+q_1)*(Q+q_2)*...*(Q+q_m)
147  * n(Q) = (Q+p_1)*(Q+p_2)*... *(Q+p_m)
148  * m = SIRatDeg
149  *
150  * The rational function n(x)/d(x) is the optimal rational
151  * approximation to the inverse square root of N(x)/D(x) which in
152  * turn is the optimal rational approximation to x^(-alpha).
153  * Here, alpha = 1/2
154  *
155  * To solve {n(Q)*[d(Q)]^(-1) * eta} the partial fraction expansion is
156  * used in combination with a multishift solver.
157  */
159  {
160  START_CODE();
161 
162  // SelfIdentification/Encapsultaion Rule
163  XMLWriter& xml_out = TheXMLLogWriter::Instance();
164  push(xml_out, "OneFlavorRatioRatRatExactWilsonTypeFermMonomial5DRefresh");
165 
166  // Heatbath all the fields
167 
168  // Get at the ferion action for piece i
170 
171  // Create a Connect State, apply fermionic boundaries
172  Handle< FermState<Phi,P,Q> > f_state(FA.createState(s.getQ()));
173 
174  // Force terms
175  const int N5 = FA.size();
176 
177  // Pseudofermions for M term
178  multi1d<int> n_m_count(getNPF());
179  getPhi().resize(getNPF()); // Will hold nth-root pseudoferms
180  {
181  // Get multi-shift system solver
183 
184  // Get linear operator
186 
187  // Partial Fraction Expansion coeffs for heat-bath
188  const RemezCoeff_t& sipfe = getNumerSIPFE();
189 
190  multi1d<Phi> eta(N5);
191 
192  // Loop over the pseudoferms
193  for(int n=0; n < getNPF(); ++n)
194  {
195  // Fill the eta field with gaussian noise
196  eta = zero;
197  for(int i=0; i < N5; ++i)
198  gaussian(eta[i], M->subset());
199 
200  // Account for fermion BC by modifying the proposed field
201  FA.getFermBC().modifyF(eta);
202 
203  // Temporary: Move to correct normalisation
204  for(int i=0; i < N5; ++i)
205  eta[i][M->subset()] *= sqrt(0.5);
206 
207  // The multi-shift inversion
208  multi1d< multi1d<Phi> > X;
209  SystemSolverResults_t res = (*invMdagM)(X, sipfe.pole, eta);
210  n_m_count[n] = res.n_count;
211 
212  // Sanity checks
213  if (X.size() != sipfe.pole.size())
214  QDP_error_exit("%s : sanity failure, internal size not getSIPartFracRoot size", __func__);
215 
216  if (X[0].size() != N5)
217  QDP_error_exit("%s : sanity failure, internal size not N5", __func__);
218 
219  // Weight solns to make final PF field
220  getPhi()[n].resize(N5);
221  getPhi()[n] = zero;
222  // Loop over each 5d slice
223  for(int j=0; j < N5; ++j)
224  {
225  getPhi()[n][j][M->subset()] = sipfe.norm * eta[j];
226  for(int i=0; i < X.size(); ++i)
227  getPhi()[n][j][M->subset()] += sipfe.res[i] * X[i][j];
228  }
229  }
230  }
231 
232  write(xml_out, "n_m_count", n_m_count);
233  pop(xml_out);
234 
235  END_CODE();
236  }
237 
238 
239  //! Copy internal fields
240  virtual void setInternalFields(const Monomial<P,Q>& m)
241  {
242  START_CODE();
243 
244  try {
246 
247  // Do a resize here -- otherwise if the fields have not yet
248  // been refreshed there may be trouble
249  getPhi().resize(fm.getPhi().size());
250  for(int i=0 ; i < fm.getPhi().size(); i++) {
251  (getPhi())[i] = (fm.getPhi())[i];
252  }
253  }
254  catch(std::bad_cast) {
255  QDPIO::cerr << "Failed to cast input Monomial to OneFlavorRatioRatRatExactWilsonTypeFermMonomial5D" << std::endl;
256  QDP_abort(1);
257  }
258 
259  END_CODE();
260  }
261 
262 
263  //! Compute action on the appropriate subset
264  /*!
265  * This may only be a Piece Of The Action
266  *
267  * This function measures the pseudofermion contribution to the Hamiltonian
268  * for the case of rational evolution (with polynomials n(x) and d(x),
269  * of degree SRatDeg
270  *
271  * S_f = chi_dag * (n(A)*d(A)^(-1))^2* chi
272  *
273  * where A is M^dag*M
274  *
275  * The rational function n(x)/d(x) is the optimal rational
276  * approximation to the square root of N(x)/D(x) which in
277  * turn is the optimal rational approximation to x^(-alpha).
278  * Here, alpha = 1/2
279  */
280  virtual Double S_subset(const AbsFieldState<P,Q>& s) const
281  {
282  START_CODE();
283 
284  XMLWriter& xml_out = TheXMLLogWriter::Instance();
285  push(xml_out, "S_subset");
286 
288 
289  // Create a Connect State, apply fermionic boundaries
290  Handle< FermState<Phi,P,Q> > bc_g_state(FA.createState(s.getQ()));
291 
292  // Force terms
293  const int N5 = FA.size();
294 
295  // Action for M term
296  Double action_m = zero;
297  multi1d<int> n_m_count(getNPF());
298  {
299  // Get multi-shift system solver
301 
302  // Get linear operator
304 
305  // Partial Fraction Expansion coeffs for action
306  const RemezCoeff_t& spfe = getNumerSPFE();
307 
308  // Get X out here via multisolver
309  multi1d< multi1d<Phi> > X;
310  multi1d<Phi> tmp(N5);
311 
312  // Loop over the pseudoferms
313  for(int n=0; n < getNPF(); ++n)
314  {
315  // The multi-shift inversion
316  SystemSolverResults_t res = (*invMdagM)(X, spfe.pole, getPhi()[n]);
317  n_m_count[n] = res.n_count;
318 
319  // Sanity checks
320  if (X.size() != spfe.pole.size())
321  QDP_error_exit("%s : sanity failure, internal size not getSPartFracRoot size", __func__);
322 
323  if (X[0].size() != N5)
324  QDP_error_exit("%s : sanity failure, internal size not N5", __func__);
325 
326  // Weight solns
327  // Loop over each 5d slice
328  for(int j=0; j < N5; ++j)
329  {
330  tmp[j][M->subset()] = spfe.norm * getPhi()[n][j];
331  for(int i=0; i < X.size(); ++i)
332  tmp[j][M->subset()] += spfe.res[i] * X[i][j];
333  }
334 
335  // Action on the subset
336  action_m += norm2(tmp, M->subset());
337  }
338  }
339 
340  write(xml_out, "n_m_count", n_m_count);
341  write(xml_out, "S_m", action_m);
342  Double action = action_m;
343  write(xml_out, "S", action);
344  pop(xml_out);
345 
346  END_CODE();
347 
348  return action;
349  }
350 
351 
352  protected:
353  //! Get at fermion action
355  {return getNumerFermAct();}
356 
357  //! Get at fermion action
358  virtual const WilsonTypeFermAct5D<Phi,P,Q>& getNumerFermAct() const = 0;
359 
360  //! Get at fermion action
361  virtual const WilsonTypeFermAct5D<Phi,P,Q>& getDenomFermAct() const = 0;
362 
363  //! Get inverter params
364  virtual const GroupXML_t& getNumerActionInvParams(void) const = 0;
365 
366  //! Get inverter params
367  virtual const GroupXML_t& getNumerForceInvParams(void) const = 0;
368 
369  //! Get inverter params
370  virtual const GroupXML_t& getDenomActionInvParams(void) const = 0;
371 
372  //! Get inverter params
373  virtual const GroupXML_t& getDenomForceInvParams(void) const = 0;
374 
375  //! Return the partial fraction expansion for the force calc
376  virtual const RemezCoeff_t& getNumerFPFE() const = 0;
377 
378  //! Return the partial fraction expansion for the action calc
379  virtual const RemezCoeff_t& getNumerSPFE() const = 0;
380 
381  //! Return the partial fraction expansion for the heat-bath
382  virtual const RemezCoeff_t& getNumerSIPFE() const = 0;
383 
384  //! Return the partial fraction expansion for the force calc
385  virtual const RemezCoeff_t& getDenomFPFE() const = 0;
386 
387  //! Return the partial fraction expansion for the action calc
388  virtual const RemezCoeff_t& getDenomSPFE() const = 0;
389 
390  //! Return the partial fraction expansion for the heat-bath
391  virtual const RemezCoeff_t& getDenomSIPFE() const = 0;
392 
393  //! Accessor for pseudofermion (read only)
394  virtual const multi1d< multi1d<Phi> >& getPhi(void) const = 0;
395 
396  //! mutator for pseudofermion
397  virtual multi1d< multi1d<Phi> >& getPhi(void) = 0;
398 
399  //! Return number of pseudofermions
400  virtual int getNPF() const = 0;
401  };
402 
403 
404  //-------------------------------------------------------------------------------------------
405  //! Exact 1 flavor unpreconditioned fermact monomial living in extra dimensions
406  /*! @ingroup monomial
407  *
408  * Exact 1 flavor unpreconditioned fermact monomial.
409  */
410  template<typename P, typename Q, typename Phi>
412  {
413  public:
414  //! virtual destructor:
416 
417  //! Compute the total action
418  virtual Double S(const AbsFieldState<P,Q>& s)
419  {
420  START_CODE();
421 
422  XMLWriter& xml_out=TheXMLLogWriter::Instance();
423  push(xml_out, "OneFlavorRatioRatRatExactUnprecWilsonTypeFermMonomial5D");
424 
425  Double action = this->S_subset(s);
426 
427  write(xml_out, "S", action);
428  pop(xml_out);
429 
430  END_CODE();
431 
432  return action;
433  }
434 
435 
436  protected:
437  //! Get at fermion action
438  virtual const WilsonTypeFermAct5D<Phi,P,Q>& getNumerFermAct() const = 0;
439 
440  //! Get at fermion action
441  virtual const WilsonTypeFermAct5D<Phi,P,Q>& getDenomFermAct() const = 0;
442  };
443 
444 
445  //-------------------------------------------------------------------------------------------
446  //! Exact 1 flavor even-odd preconditioned fermact monomial living in extra dimensions
447  /*! @ingroup monomial
448  *
449  * Exact 1 flavor even-odd preconditioned fermact monomial.
450  * Can supply a default dsdq algorithm
451  */
452  template<typename P, typename Q, typename Phi>
454  {
455  public:
456  //! virtual destructor:
458 
459  //! Even even contribution (eg ln det Clover)
460  virtual Double S_even_even(const AbsFieldState<P,Q>& s) = 0;
461 
462  //! Compute the odd odd contribution (eg
464  {
465  return this->S_subset(s);
466  }
467 
468  //! Compute the total action
470  {
471  START_CODE();
472 
473  XMLWriter& xml_out=TheXMLLogWriter::Instance();
474  push(xml_out, "OneFlavorRatioRatRatExactEvenOddPrecWilsonTypeFermMonomial5D");
475 
476  Double action_e = S_even_even(s);
477  Double action_o = S_odd_odd(s);
478  Double action = action_e + action_o;
479 
480  write(xml_out, "S_even_even", action_e);
481  write(xml_out, "S_odd_odd", action_o);
482  write(xml_out, "S", action);
483  pop(xml_out);
484 
485  END_CODE();
486 
487  return action;
488  }
489 
490  protected:
491  //! Get at fermion action
493 
494  //! Get at fermion action
496  };
497 
498  //-------------------------------------------------------------------------------------------
499  //! Exact 1 flavor even-odd preconditioned fermact monomial living in extra dimensions
500  /*! @ingroup monomial
501  *
502  * Exact 1 flavor even-odd preconditioned fermact monomial.
503  * Can supply a default dsdq algorithm
504  */
505  template<typename P, typename Q, typename Phi>
508  {
509  public:
510  //! virtual destructor:
512 
513  //! Even even contribution (eg ln det Clover)
515  return Double(0);
516  }
517 
518 
519  protected:
520  //! Get at fermion action
522 
523  //! Get at fermion action
525  };
526 
527 }
528 
529 #endif
Monomials - gauge action or fermion binlinear contributions for HMC.
Abstract field state.
Definition: field_state.h:27
virtual DiffLinearOperatorArray< T, P, Q > * linOp(Handle< FermState< T, P, Q > > state) const =0
Produce a linear operator for this action.
Even-odd preconditioned Wilson-like fermion actions including derivatives.
Fermionic monomials (binlinears in fermion fields)
Definition: abs_monomial.h:280
virtual int size() const =0
Expected length of array index.
virtual const FermBC< T, P, Q > & getFermBC() const
Return the fermion BC object for this action.
Definition: fermact.h:79
virtual FermState< T, P, Q > * createState(const Q &q) const
Given links (coordinates Q) create the state needed for the linear operators.
Definition: fermact.h:59
Class for counted reference semantics.
Definition: handle.h:33
An abstract monomial class, for inexact algorithms.
Definition: abs_monomial.h:43
Exact 1 flavor even-odd preconditioned fermact monomial living in extra dimensions.
virtual const EvenOddPrecWilsonTypeFermAct5D< Phi, P, Q > & getDenomFermAct() const =0
Get at fermion action.
virtual Double S_even_even(const AbsFieldState< P, Q > &s)
Even even contribution (eg ln det Clover)
virtual const EvenOddPrecWilsonTypeFermAct5D< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
Exact 1 flavor even-odd preconditioned fermact monomial living in extra dimensions.
virtual Double S_even_even(const AbsFieldState< P, Q > &s)=0
Even even contribution (eg ln det Clover)
Double S(const AbsFieldState< P, Q > &s)
Compute the total action.
virtual const EvenOddPrecWilsonTypeFermAct5D< Phi, P, Q > & getDenomFermAct() const =0
Get at fermion action.
virtual const EvenOddPrecWilsonTypeFermAct5D< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
virtual Double S_odd_odd(const AbsFieldState< P, Q > &s)
Compute the odd odd contribution (eg.
Exact 1 flavor unpreconditioned fermact monomial living in extra dimensions.
virtual Double S(const AbsFieldState< P, Q > &s)
Compute the total action.
virtual const WilsonTypeFermAct5D< Phi, P, Q > & getDenomFermAct() const =0
Get at fermion action.
virtual const WilsonTypeFermAct5D< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
virtual const RemezCoeff_t & getDenomSIPFE() const =0
Return the partial fraction expansion for the heat-bath.
virtual const WilsonTypeFermAct5D< Phi, P, Q > & getDenomFermAct() const =0
Get at fermion action.
virtual void dsdq(P &F, const AbsFieldState< P, Q > &s)
Compute dsdq for the system...
virtual Double S(const AbsFieldState< P, Q > &s)=0
Compute the total action.
virtual multi1d< multi1d< Phi > > & getPhi(void)=0
mutator for pseudofermion
virtual const GroupXML_t & getDenomForceInvParams(void) const =0
Get inverter params.
virtual void refreshInternalFields(const AbsFieldState< P, Q > &s)
Refresh pseudofermions.
virtual const RemezCoeff_t & getNumerSPFE() const =0
Return the partial fraction expansion for the action calc.
virtual const RemezCoeff_t & getDenomFPFE() const =0
Return the partial fraction expansion for the force calc.
virtual const GroupXML_t & getNumerForceInvParams(void) const =0
Get inverter params.
virtual int getNPF() const =0
Return number of pseudofermions.
virtual void setInternalFields(const Monomial< P, Q > &m)
Copy internal fields.
virtual const RemezCoeff_t & getNumerSIPFE() const =0
Return the partial fraction expansion for the heat-bath.
virtual const GroupXML_t & getNumerActionInvParams(void) const =0
Get inverter params.
virtual const GroupXML_t & getDenomActionInvParams(void) const =0
Get inverter params.
virtual const RemezCoeff_t & getDenomSPFE() const =0
Return the partial fraction expansion for the action calc.
virtual const WilsonTypeFermAct5D< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
virtual const WilsonTypeFermAct5D< Phi, P, Q > & getFermAct() const
Get at fermion action.
virtual const RemezCoeff_t & getNumerFPFE() const =0
Return the partial fraction expansion for the force calc.
virtual Double S_subset(const AbsFieldState< P, Q > &s) const
Compute action on the appropriate subset.
virtual const multi1d< multi1d< Phi > > & getPhi(void) const =0
Accessor for pseudofermion (read only)
static T & Instance()
Definition: singleton.h:432
Wilson-like fermion actions.
Definition: fermact.orig.h:403
virtual MdagMMultiSystemSolverArray< T > * mInvMdagM(Handle< FermState< T, P, Q > > state, const GroupXML_t &invParam) const
Return a multi-shift linear operator solver for this action to solve (MdagM+shift)*psi=chi.
int mu
Definition: cool.cc:24
Even-odd const determinant Wilson-like fermact.
Helper function for calculating forces.
void write(XMLWriter &xml, const std::string &path, const AsqtadFermActParams &param)
Writer parameters.
void monitorForces(XMLWriter &xml_out, const std::string &path, const multi1d< LatticeColorMatrix > &F)
Calculate and write out forces.
unsigned j
Definition: ldumul_w.cc:35
unsigned n
Definition: ldumul_w.cc:36
static int m[4]
Definition: make_seeds.cc:16
Nd
Definition: meslate.cc:74
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
gaussian(aux)
QDP_error_exit("too many BiCG iterations", n_count, rsd_sq, cp, c, re_rvr, im_rvr, re_a, im_a, re_b, im_b)
LatticeFermion tmp
Definition: mespbg5p_w.cc:36
push(xml_out,"Condensates")
int i
Definition: pbg5p_w.cc:55
@ MINUS
Definition: chromabase.h:45
@ PLUS
Definition: chromabase.h:45
pop(xml_out)
LatticeFermion eta
Definition: mespbg5p_w.cc:37
START_CODE()
const WilsonTypeFermAct< multi1d< LatticeFermion > > Handle< const ConnectState > state
Definition: pbg5p_w.cc:28
Double zero
Definition: invbicg.cc:106
multi1d< LatticeFermion > s(Ncb)
FloatingPoint< double > Double
Definition: gtest.h:7351
Remez algorithm coefficients.
Hold group xml and type id.
Convenient structure to package Remez coeffs.
Definition: remez_coeff.h:19
multi1d< Real > pole
Definition: remez_coeff.h:21
multi1d< Real > res
Definition: remez_coeff.h:20
Holds return info from SystemSolver call.
Definition: syssolver.h:17
multi1d< LatticeColorMatrix > P
Definition: t_clover.cc:13
Wilson-like fermion actions.
static INTERNAL_PRECISION F