CHROMA
two_flavor_ratio_conv_rat_monomial5d_w.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 /*! @file
4  * @brief Two flavor Monomials - gauge action or fermion binlinear contributions for HMC
5  */
6 
7 #ifndef __two_flavor_ratio_conv_rat_monomial5d_w_h__
8 #define __two_flavor_ratio_conv_rat_monomial5d_w_h__
9 
16 
17 #include <typeinfo> // For std::bad_cast
18 
19 namespace Chroma
20 {
21  //-------------------------------------------------------------------------------------------
22  //! Exact 2 degen flavor RatioConvRat like fermact monomial in extra dimensions
23  /*! @ingroup monomial
24  *
25  * Exact 2 degen flavor RatioConvRat like fermact monomial. Preconditioning is not
26  * specified yet.
27  * Can supply a default dsdq and pseudoferm refresh algorithm
28  *
29  * Note most of the code is the same here as in the usual 2 flavour
30  * case. The only real change is that instead of the PV field, I now
31  * use the preconditioning matrix. -- This leads to evil code duplication.
32  * Think about abstracting this better.
33  * CAVEAT: I assume there is only 1 pseudofermion field in the following
34  * so called TwoFlavorExact actions.
35  */
36  template<typename P, typename Q, typename Phi>
38  {
39  public:
40  //! virtual destructor:
42 
43  //! Compute the total action
44  virtual Double S(const AbsFieldState<P,Q>& s) = 0;
45 
46  //! Compute dsdq for the system...
47  /*! Actions of the form chi^dag*(M^dag*M)*chi */
48  virtual void dsdq(P& F, const AbsFieldState<P,Q>& s)
49  {
50  START_CODE();
51 
52  // SelfIdentification/Encapsultaion Rule
53  XMLWriter& xml_out = TheXMLLogWriter::Instance();
54  push(xml_out, "TwoFlavorExactRatioConvRatWilsonTypeFermMonomial5D");
55 
56  /**** Identical code for unprec and even-odd prec case *****/
57 
58  // S_f = chi^dag*M_2*(M^dag*M)^(-1)*M_2^dag*chi
59  // Here, M is some 5D operator and M_2 is the preconditioning
60  // linop, which plays a role identical to the Pauli-Villars matrix
61  // in the normal case. The Pauli Villars matrices cancel between
62  // numerator and denominator.
63  //
64  // Need
65  // dS_f/dU = chi^dag * dM_2 * (M^dag*M)^(-1) * M_2^dag * chi
66  // - chi^dag * M_2 * (M^dag*M)^(-1) * [d(M^dag)*M + M^dag*dM] * M_2^dag * (M^dag*M)^(-1) * chi
67  // + chi^dag * M_2 * (M^dag*M)^(-1) * d(M_2^dag) * chi
68  //
69  // = chi^dag * dM_2 * psi
70  // - psi^dag * [d(M^dag)*M + M^dag*dM] * psi
71  // + psi^dag * d(M_2^dag) * chi
72  //
73  // where psi = (M^dag*M)^(-1) * M_2^dag * chi
74  //
75  // In Balint's notation, the result is
76  // \dot{S} = chi^dag*\dot(M_2)*X - X^dag*\dot{M}^\dag*Y - Y^dag\dot{M}*X + X*\dot{M_2}^dag*chi
77  // where
78  // X = (M^dag*M)^(-1)*M_2^dag*chi Y = M*X = (M^dag)^(-1)*M_2^dag*chi
79  // In Robert's notation, X -> psi .
80  //
83 
84  // Create a state for linop
86 
87  // Get linear operator
89 
90  // Get the mass-style preconditioning linear operator
92 
93  // Get/construct the pseudofermion solution
94  multi1d<Phi> X(FA.size()), Y(FA.size());
95 
96  // Move these to get X
97  int n_count = this->getX(X,s);
98 
99  (*M)(Y, X, PLUS);
100 
101  // First M_2 contribution
102  M_2->deriv(F, getPhi(), X, PLUS);
103 
104  // Last M_2 contribution
105  P F_tmp;
106  M_2->deriv(F_tmp, X, getPhi(), MINUS);
107  F += F_tmp; // NOTE SIGN
108 
109  P FM;
110  M->deriv(FM, X, Y, MINUS);
111 
112  // fold M^dag into X^dag -> Y !!
113  M->deriv(F_tmp, Y, X, PLUS);
114  FM += F_tmp; // NOTE SIGN
115 
116  // Combine forces
117  F -= FM;
118 
119  // Recurse only once
120  state->deriv(F);
121 
122  write(xml_out, "n_count", n_count);
123  monitorForces(xml_out, "Forces", F);
124 
125  pop(xml_out);
126 
127  END_CODE();
128  }
129 
130  //! Refresh pseudofermions
131  virtual void refreshInternalFields(const AbsFieldState<P,Q>& field_state)
132  {
133  START_CODE();
134 
135  // Heatbath all the fields
136 
137  // Get at the ferion action for piece i
140 
141  // Create a Connect State, apply fermionic boundaries
142  Handle< FermState<Phi,P,Q> > f_state(FA.createState(field_state.getQ()));
143 
144  // Create a linear operator
146 
147  // Get the mass-style preconditioning linear operator
148  Handle< DiffLinearOperatorArray<Phi,P,Q> > M_2(precFA.linOp(f_state));
149 
150  const int N5 = FA.size();
151  multi1d<Phi> eta(N5);
152  eta = zero;
153 
154  getPhi() = zero;
155 
156 
157  // Fill the eta field with gaussian noise
158  for(int s=0; s < N5; ++s) {
159  gaussian(eta[s], M->subset());
160  }
161 
162  // Account for fermion BC by modifying the proposed field
163  FA.getFermBC().modifyF(eta);
164 
165  // Temporary: Move to correct normalisation
166  for(int s=0; s < N5; ++s)
167  eta[s][M->subset()] *= sqrt(0.5);
168 
169  // Build phi = M_2 * (M_2^dag*M_2)^(-1) * M^dag * eta
170  multi1d<Phi> tmp(N5);
171 
172  tmp=zero;
173 
174  (*M)(tmp, eta, MINUS);
175 
176  // Solve (V^dag*V)*eta = tmp
177  // Get system solver
178  Handle< MdagMSystemSolverArray<Phi> > invMdagM(precFA.invMdagM(f_state, getNumerInvParams()));
179 
180  // Do the inversion
181  SystemSolverResults_t res = (*invMdagM)(eta, tmp);
182 
183  // Finally, get phi
184  (*M_2)(getPhi(), eta, PLUS);
185 
186  // Reset the chronological predictor
187  QDPIO::cout << "TwoFlavRatioConvRatWilson5DMonomial: resetting Predictor at end of field refresh" << std::endl;
188  getMDSolutionPredictor().reset();
189 
190  END_CODE();
191  }
192 
193  virtual void setInternalFields(const Monomial<P,Q>& m)
194  {
195  START_CODE();
196 
197  try {
199 
200  // Do a resize here -- otherwise if the fields have not yet
201  // been refreshed there may be trouble
202  getPhi().resize(fm.getPhi().size());
203 
204  for(int i=0 ; i < fm.getPhi().size(); i++) {
205  (getPhi())[i] = (fm.getPhi())[i];
206  }
207  }
208  catch(std::bad_cast) {
209  QDPIO::cerr << "Failed to cast input Monomial to TwoFlavorExactRatioConvRatWilsonTypeFermMonomial5D" << std::endl;
210  QDP_abort(1);
211  }
212 
213 
214  END_CODE();
215  }
216 
217  //! Reset predictors
218  virtual void resetPredictors() {
219  getMDSolutionPredictor().reset();
220 
221  }
222 
223  protected:
224  //! Accessor for pseudofermion with Pf index i (read only)
225  virtual const multi1d<Phi>& getPhi() const = 0;
226 
227  //! mutator for pseudofermion with Pf index i
228  virtual multi1d<Phi>& getPhi() = 0;
229 
230  //! Get at fermion action
232  {return getNumerFermAct();}
233 
234  //! Get at fermion action
235  virtual const WilsonTypeFermAct5D<Phi,P,Q>& getNumerFermAct() const = 0;
236 
238 
239  //! Get parameters for the inverter
240  virtual const GroupXML_t& getNumerInvParams() const = 0;
241 
242  //! Get inverter params
243  virtual const GroupXML_t& getDenomActionInvParams() const = 0;
244 
245  //! Get inverter params
246  virtual const GroupXML_t& getDenomForceInvParams() const = 0;
247 
248  //! Return the partial fraction expansion for the force calc
249  virtual const RemezCoeff_t& getDenomFPFE() const = 0;
250 
251  //! Return the partial fraction expansion for the action calc
252  virtual const RemezCoeff_t& getDenomSPFE() const = 0;
253 
254  //! Return the partial fraction expansion for the heat-bath
255  virtual const RemezCoeff_t& getDenomSIPFE() const = 0;
256 
257  //! Get the initial guess predictor
259 
260  //! Get (M^dagM)^{-1} phi
261  virtual int getX(multi1d<Phi>& X, const AbsFieldState<P,Q>& s)
262  {
263  START_CODE();
264 
265  // Grab the fermact
268 
269  // Make the state
271 
272  // Get linop
274  // Get PV
276 
277  multi1d<Phi> MPrecDagPhi(FA.size());
278 
279  (*M_prec)(MPrecDagPhi, getPhi(), MINUS);
280 
281  // Get system solver
283 
284  // CG Chrono predictor needs MdagM
286  (getMDSolutionPredictor())(X, *MdagM, MPrecDagPhi);
287 
288  // Do the inversion
289  SystemSolverResults_t res = (*invMdagM)(X, MPrecDagPhi);
290 
291  // Register the new std::vector
292  (getMDSolutionPredictor()).newVector(X);
293 
294  return res.n_count;
295 
296  END_CODE();
297  }
298 
299  };
300 
301 
302  //-------------------------------------------------------------------------------------------
303  //! Exact 2 degen flavor unpreconditioned fermact monomial living in extra dimensions
304  /*! @ingroup monomial
305  *
306  * Exact 2 degen flavor unpreconditioned fermact monomial.
307  *
308  * CAVEAT: I assume there is only 1 pseudofermion field in the following
309  * so called TwoFlavorExact actions.
310  */
311  template<typename P, typename Q, typename Phi>
313  {
314  public:
315  //! virtual destructor:
317 
318  //! Compute the total action
319  virtual Double S(const AbsFieldState<P,Q>& s)
320  {
321  START_CODE();
322 
323  // SelfEncapsulation/Identification Rule
324  XMLWriter& xml_out = TheXMLLogWriter::Instance();
325  push(xml_out, "TwoFlavorExactUnprecRatioConvRatWilsonTypeFermMonomial5D");
326 
327  // Get at the ferion action for piece i
329 
330  // Create a Connect State, apply fermionic boundaries
331  Handle< FermState<Phi,P,Q> > f_state(FA_prec.createState(s.getQ()));
332  Handle< DiffLinearOperatorArray<Phi,P,Q> > M_prec(FA_prec.linOp(f_state));
333 
334  multi1d<Phi> X(FA_prec.size());
335  multi1d<Phi> tmp(FA_prec.size());
336 
337  // Paranoia -- to deal with subsets.
338  tmp = zero;
339 
340  // Energy calc does not use chrono predictor
341  X = zero;
342 
343  // X is now (M^dagM)^{-1} V^{dag} phi
344 
345  // getX() now always uses Chrono predictor. Best to Nuke it for
346  // energy calcs
347  QDPIO::cout << "TwoFlavRatioConvRatWilson5DMonomial: resetting Predictor before energy calc solve" << std::endl;
348  getMDSolutionPredictor().reset();
349  int n_count = this->getX(X,s);
350 
351  // tmp is now V (M^dag M)^{-1} V^{dag} phi
352  (*M_prec)(tmp, X, PLUS);
353 
354  // Action on the entire lattice
355  Double action = zero;
356  for(int s=0; s < FA_prec.size(); ++s)
357  action += innerProductReal(getPhi()[s], tmp[s]);
358 
359  write(xml_out, "n_count", n_count);
360  write(xml_out, "S", action);
361  pop(xml_out);
362 
363  END_CODE();
364 
365  return action;
366  }
367 
368 
369  protected:
370  //! Accessor for pseudofermion with Pf index i (read only)
371  virtual const multi1d<Phi>& getPhi() const = 0;
372 
373  //! mutator for pseudofermion with Pf index i
374  virtual multi1d<Phi>& getPhi() = 0;
375 
376  //! Get at fermion action
378 
379  //! Get at fermion action
381 
382  //! Get the initial guess predictor
384  };
385 
386 
387  //-------------------------------------------------------------------------------------------
388  //! Exact 2 degen flavor even-odd preconditioned fermact monomial living in extra dimensions
389  /*! @ingroup monomial
390  *
391  * Exact 2 degen flavor even-odd preconditioned fermact monomial.
392  * Can supply a default dsdq algorithm
393  */
394  template<typename P, typename Q, typename Phi>
396  {
397  public:
398  //! virtual destructor:
400 
401  //! Even even contribution (eg ln det Clover)
402  virtual Double S_even_even(const AbsFieldState<P,Q>& s) = 0;
403 
404  //! Compute the odd odd contribution (eg
406  {
407  START_CODE();
408 
409  XMLWriter& xml_out = TheXMLLogWriter::Instance();
410  push(xml_out, "S_odd_odd");
411 
414 
415  Handle< FermState<Phi,P,Q> > bc_g_state(FA.createState(s.getQ()));
416 
417  // Need way to get gauge state from AbsFieldState<P,Q>
419 
420  Handle< EvenOddPrecLinearOperatorArray<Phi,P,Q> > M_prec(FA_prec.linOp(bc_g_state));
421  // Get the X fields
422  multi1d<Phi> X(FA.size());
423 
424  // X is now (M^dag M)^{-1} V^dag phi
425 
426  // Chrono predictor not used in energy calculation
427  X = zero;
428 
429  // Get X now always uses predictor. Best to nuke it therefore
430  QDPIO::cout << "TwoFlavRatioConvRatWilson5DMonomial: resetting Predictor before energy calc solve" << std::endl;
431  getMDSolutionPredictor().reset();
432  int n_count = this->getX(X, s);
433 
434  multi1d<Phi> tmp(FA.size());
435  (*M_prec)(tmp, X, PLUS);
436 
437  Double action = zero;
438  // Total odd-subset action. NOTE: QDP has norm2(multi1d) but not innerProd
439  for(int s=0; s < FA.size(); ++s)
440  action += innerProductReal(getPhi()[s], tmp[s], lin->subset());
441 
442 
443  write(xml_out, "n_count", n_count);
444  write(xml_out, "S_oo", action);
445  pop(xml_out);
446 
447  END_CODE();
448 
449  return action;
450  }
451 
452  //! Compute the total action
454  {
455  START_CODE();
456 
457  XMLWriter& xml_out=TheXMLLogWriter::Instance();
458  push(xml_out, "TwoFlavorExactEvenOddPrecRatioConvRatWilsonTypeFermMonomial5D");
459 
460  Double action = S_even_even(s) + S_odd_odd(s);
461 
462  write(xml_out, "S", action);
463  pop(xml_out);
464 
465  END_CODE();
466 
467  return action;
468  }
469 
470  protected:
471  //! Get at fermion action
474 
475  //! Get the initial guess predictor
477 
478  //! Accessor for pseudofermion
479  virtual const multi1d<Phi>& getPhi() const = 0;
480 
481  //! mutator for pseudofermion
482  virtual multi1d<Phi>& getPhi() = 0;
483  };
484 
485  //-------------------------------------------------------------------------------------------
486  //! Exact 2 degen flavor even-odd preconditioned fermact monomial living in extra dimensions
487  /*! @ingroup monomial
488  *
489  * Exact 2 degen flavor even-odd preconditioned fermact monomial.
490  * Can supply a default dsdq algorithm
491  */
492  template<typename P, typename Q, typename Phi>
494  {
495  public:
496  //! virtual destructor:
498 
499  //! Even even contribution (eg ln det Clover)
501  return Double(0);
502  }
503 
504  protected:
505  //! Get at fermion action
508  };
509 
510 
511 
512 }
513 
514 
515 #endif
Monomials - gauge action or fermion binlinear contributions for HMC.
Chronological predictor for HMC.
Abstract interface for a Chronological Solution predictor in 5D.
Abstract field state.
Definition: field_state.h:27
virtual const Q & getQ(void) const =0
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.
Even-odd preconditioned Wilson-like fermion actions including derivatives.
virtual EvenOddPrecLinearOperatorArray< T, P, Q > * linOp(Handle< FermState< T, P, Q > > state) const =0
Override to produce an even-odd prec. linear operator for this action.
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
static T & Instance()
Definition: singleton.h:432
Exact 2 degen flavor even-odd preconditioned fermact monomial living in extra dimensions.
virtual const EvenOddPrecConstDetWilsonTypeFermAct5D< Phi, P, Q > & getDenomFermAct() const =0
virtual const EvenOddPrecConstDetWilsonTypeFermAct5D< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
virtual Double S_even_even(const AbsFieldState< P, Q > &s)
Even even contribution (eg ln det Clover)
Exact 2 degen flavor even-odd preconditioned fermact monomial living in extra dimensions.
virtual const EvenOddPrecWilsonTypeFermAct5D< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
virtual multi1d< Phi > & getPhi()=0
mutator for pseudofermion
virtual AbsChronologicalPredictor5D< Phi > & getMDSolutionPredictor()=0
Get the initial guess predictor.
virtual const multi1d< Phi > & getPhi() const =0
Accessor for pseudofermion.
virtual const EvenOddPrecWilsonTypeFermAct5D< Phi, P, Q > & getDenomFermAct() const =0
virtual Double S_odd_odd(const AbsFieldState< P, Q > &s)
Compute the odd odd contribution (eg.
virtual Double S_even_even(const AbsFieldState< P, Q > &s)=0
Even even contribution (eg ln det Clover)
Exact 2 degen flavor RatioConvRat like fermact monomial in extra dimensions.
virtual const multi1d< Phi > & getPhi() const =0
Accessor for pseudofermion with Pf index i (read only)
virtual int getX(multi1d< Phi > &X, const AbsFieldState< P, Q > &s)
Get (M^dagM)^{-1} phi.
virtual const WilsonTypeFermAct5D< Phi, P, Q > & getFermAct() const
Get at fermion action.
virtual const WilsonTypeFermAct5D< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
virtual const GroupXML_t & getNumerInvParams() const =0
Get parameters for the inverter.
virtual void setInternalFields(const Monomial< P, Q > &m)
Copy pseudofermions if any.
virtual const RemezCoeff_t & getDenomSIPFE() const =0
Return the partial fraction expansion for the heat-bath.
virtual const RemezCoeff_t & getDenomFPFE() const =0
Return the partial fraction expansion for the force calc.
virtual Double S(const AbsFieldState< P, Q > &s)=0
Compute the total action.
virtual multi1d< Phi > & getPhi()=0
mutator for pseudofermion with Pf index i
virtual void refreshInternalFields(const AbsFieldState< P, Q > &field_state)
Refresh pseudofermions.
virtual AbsChronologicalPredictor5D< Phi > & getMDSolutionPredictor()=0
Get the initial guess predictor.
virtual const GroupXML_t & getDenomActionInvParams() const =0
Get inverter params.
virtual const GroupXML_t & getDenomForceInvParams() const =0
Get inverter params.
virtual void dsdq(P &F, const AbsFieldState< P, Q > &s)
Compute dsdq for the system...
virtual const WilsonTypeFermAct5D< Phi, P, Q > & getDenomFermAct() const =0
virtual const RemezCoeff_t & getDenomSPFE() const =0
Return the partial fraction expansion for the action calc.
Exact 2 degen flavor unpreconditioned fermact monomial living in extra dimensions.
virtual Double S(const AbsFieldState< P, Q > &s)
Compute the total action.
virtual const multi1d< Phi > & getPhi() const =0
Accessor for pseudofermion with Pf index i (read only)
virtual const UnprecWilsonTypeFermAct5D< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
virtual AbsChronologicalPredictor5D< Phi > & getMDSolutionPredictor()=0
Get the initial guess predictor.
virtual const UnprecWilsonTypeFermAct5D< Phi, P, Q > & getDenomFermAct() const =0
Get at fermion action.
virtual multi1d< Phi > & getPhi()=0
mutator for pseudofermion with Pf index i
Unpreconditioned Wilson-like fermion actions in extra dims with derivatives.
Definition: fermact.orig.h:571
Wilson-like fermion actions.
Definition: fermact.orig.h:403
virtual MdagMSystemSolverArray< T > * invMdagM(Handle< FermState< T, P, Q > > state, const GroupXML_t &invParam) const
Return a linear operator solver for this action to solve MdagM*psi=chi.
virtual DiffLinearOperatorArray< T, P, Q > * lMdagM(Handle< FermState< T, P, Q > > state) const
Produce a linear operator M^dag.M for this action.
Definition: fermact.orig.h:410
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.
static int m[4]
Definition: make_seeds.cc:16
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
gaussian(aux)
int n_count
Definition: invbicg.cc:78
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
Holds return info from SystemSolver call.
Definition: syssolver.h:17
Handle< LinearOperator< T > > MdagM
multi1d< LatticeColorMatrix > P
Definition: t_clover.cc:13
Wilson-like fermion actions.
static INTERNAL_PRECISION F