CHROMA
two_flavor_ratio_conv_conv_multihasen_monomial_w.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! @file
3  * @brief Two-flavor collection of even-odd preconditioned 4D ferm monomials
4  */
5 
6 #ifndef __TWO_FLAVOR_RATIO_CONV_CONV_MULTIHASEN_MONOMIAL_W_H__
7 #define __TWO_FLAVOR_RATIO_CONV_CONV_MULTIHASEN_MONOMIAL_W_H__
8 
9 #include "chromabase.h"
26 
27 namespace Chroma
28 {
29 
30  // Symmetric preconditioned
31  namespace SymEvenOddPrecConstDetTwoFlavorRatioConvConvMultihasenWilsonTypeFermMonomialEnv
32  {
33  bool registerAll();
34  }
35 
36  // Asymmetric preconditioned
37  namespace EvenOddPrecConstDetTwoFlavorRatioConvConvMultihasenWilsonTypeFermMonomialEnv
38  {
39  bool registerAll();
40  }
41 
42  template<typename T, typename P, typename Q,
43  template<typename, typename, typename> class FAType,
44  template<typename, typename, typename> class LOType>
46  public ExactWilsonTypeFermMonomial<P,Q,T>
47  {
48  public:
52 
53  virtual Double S(const AbsFieldState<P, Q>& s)
54  {
55  START_CODE();
56  XMLWriter& xml_out = TheXMLLogWriter::Instance();
57  push(xml_out, "PrecConstDetTwoFlavorRatioConvConvMultihasenFermMonomial");
58 
59  // Fermion action
60  const FAType<T,P,Q>& FA = getFermAct();
61 
62  Double S=0;
63  // Get the X fields
64  T X;
65  Handle<FermState<T,P,Q> > state(FA.createState(s.getQ()));
66  Handle<LOType<T,P,Q> > base_op(FA.linOp(state));
67 
68  for(int i=0; i<numHasenTerms; ++i){
70  M(new TwistedShiftedLinOp<T,P,Q,LOType>(*base_op, mu[i]));
72  M_prec(new TwistedShiftedLinOp<T,P,Q,LOType>(*base_op, mu[i+1]));
73 
74  // Action calc doesnt use chrono predictor use zero guess
75  X[M->subset()] = zero;
76  // Reset chrono predictor
77  QDPIO::cout <<
78  "TwoFlavorRatioConvConvMultihasenWilson4DMonomial: resetting Predictor before energy calc solve" << std::endl;
80  // Get system solver
81  const GroupXML_t& invParam = getInvParams();
82  std::istringstream xml(invParam.xml);
83  XMLReader paramtop(xml);
85  invMdagM(TheMdagMFermSystemSolverFactory::Instance().createObject(
86  invParam.id, paramtop, invParam.path, state, M));
87  // M_dag_prec phi = M^{dag}_prec \phi - the RHS
88  T M_dag_prec_phi;
89  (*M_prec)(M_dag_prec_phi, getPhi(i), MINUS);
90 
91  // Solve MdagM X = eta
92  SystemSolverResults_t res = (*invMdagM)(X, M_dag_prec_phi);
93 
94  T phi_tmp = zero;
95  (*M_prec)(phi_tmp, X, PLUS);
96  Double action = innerProductReal(getPhi(i), phi_tmp, M->subset());
97  // Write out inversion number and action for every hasenbusch term
98  std::string n_count = "n_count_hasenterm_" + std::to_string(i+1);
99  std::string s_action = "S_hasenterm_" + std::to_string(i+1);
100 
101  write(xml_out, n_count, res.n_count);
102  write(xml_out, s_action, action);
103  S += action;
104  }
105  write(xml_out, "S", S);
106  pop(xml_out);
107 
108  END_CODE();
109  return S;
110  }
111 
112  // Total force of multi-hasen terms
113  virtual void dsdq(P& F, const AbsFieldState<P, Q>& s)
114  {
115  START_CODE();
116  XMLWriter& xml_out = TheXMLLogWriter::Instance();
117  push(xml_out, "TwoFlavorRatioConvConvMultihasenWilsonTypeFermMonomial");
118 
119  P F_t;
120  P F_tmp;
121  F_t.resize(Nd);
122  F_tmp.resize(Nd);
123  F.resize(Nd);
124  for(int i=0; i<Nd; ++i)
125  {
126  F_t[i] = zero;
127  F_tmp[i] = zero;
128  F[i] = zero;
129  }
130  // Fermion action
131  const FAType<T,P,Q>& FA = getFermAct();
132  // X = (M^\dag M)^(-1) M_prec^\dag \phi
133  // Y = M X
134  T X = zero;
135  T Y = zero;
136  // M_dag_prec_phi = M^\dag_prec \phi
137  T M_dag_prec_phi;
138 
139  Handle<FermState<T,P,Q> > state(FA.createState(s.getQ()));
140  Handle<LOType<T,P,Q> > base_op(FA.linOp(state));
141 
142  for(int i=0; i<numHasenTerms; ++i){
144  M(new TwistedShiftedLinOp<T,P,Q,LOType>(*base_op, mu[i]));
146  M_prec(new TwistedShiftedLinOp<T,P,Q,LOType>(*base_op, mu[i+1]));
147  // Get system solver
148  const GroupXML_t& invParam = getInvParams();
149  std::istringstream xml(invParam.xml);
150  XMLReader paramtop(xml);
152  invMdagM(TheMdagMFermSystemSolverFactory::Instance().createObject(
153  invParam.id,paramtop, invParam.path, state, M));
154 
155  (*M_prec)(M_dag_prec_phi, getPhi(i), MINUS);
156  SystemSolverResults_t res = (*invMdagM)(X, M_dag_prec_phi, getMDSolutionPredictor());
157  (*M)(Y, X, PLUS);
158 
159  // cast linearop to difflinearop
160  const DiffLinearOperator<T,P,Q>& diffM = dynamic_cast<const DiffLinearOperator<T,P,Q>&>(*M);
161  const DiffLinearOperator<T,P,Q>& diffM_prec = dynamic_cast<const DiffLinearOperator<T,P,Q>&>(*M_prec);
162 
163  // deriv part 1: \phi^\dag \dot(M_prec) X
164  diffM_prec.deriv(F_t, getPhi(i), X, PLUS);
165 
166  // deriv part 2: - X^\dag \dot(M^\dag) Y
167  diffM.deriv(F_tmp, X, Y, MINUS);
168  F_t -= F_tmp;
169 
170  // deriv part 3: - Y^\dag \dot(M) X
171  diffM.deriv(F_tmp, Y, X, PLUS);
172  F_t -= F_tmp;
173 
174  // deriv part 4: X^\dag \dot(M_prec)^\dag \phi
175  diffM_prec.deriv(F_tmp, X, getPhi(i), MINUS);
176  F_t += F_tmp;
177 
178  // total force from all Hasenbusch terms
179  F += F_t;
180 
181  // F now holds derivative with respect to possibly fat links
182  // now derive it with respect to the thin links if needs be
183  state->deriv(F);
184 
185  // Write out inversion number and action for every hasenbusch term
186  std::string n_count = "n_count_hasenterm_" + std::to_string(i+1);
187  std::string force = "Forces_hasenterm_" + std::to_string(i+1);
188 
189  write(xml_out, n_count, res.n_count);
190  monitorForces(xml_out, force, F_t);
191  }
192  // Total force from all Hasenbusch terms
193  monitorForces(xml_out, "Forces", F);
194  pop(xml_out);
195  END_CODE();
196  }
197 
199  {
200  START_CODE();
201  const FAType<T,P,Q>& FA = getFermAct();
202 
203  Handle<FermState<T,P,Q> > state(FA.createState(s.getQ()));
204  Handle<LOType<T,P,Q> > base_op(FA.linOp(state));
205  for(int i=0; i<numHasenTerms; ++i){
207  M(new TwistedShiftedLinOp<T,P,Q,LOType>(*base_op, mu[i]));
209  M_prec(new TwistedShiftedLinOp<T,P,Q,LOType>(*base_op, mu[i+1]));
210  T eta = zero;
211  gaussian(eta, M->subset());
212 
213  // Account for fermion BC by modifying the proposed field
214  FA.getFermBC().modifyF(eta);
215 
216  eta *= sqrt(0.5);
217  // Now we have to get the refreshment right:
218  // We have \eta^{\dag} \eta = \phi M_prec (M^dag M )^-1 M^dag_prec \phi
219  // so that \eta = (M^\dag)^{-1} M^{dag}_prec \phi
220  // So need to solve M^{dag}_prec \phi = M^{\dag} \eta
221  // Which we can solve as
222  // M^{dag}_prec M_prec ( M_prec^{-1} ) \phi = M^{\dag} \eta
223  //
224  // Zero out everything - to make sure there is no junk
225  // in uninitialised places
226  T eta_tmp = zero;
227  T phi_tmp = zero;
228  getPhi(i) = zero;
229 
230  (*M)(eta_tmp, eta, MINUS); // M^\dag \eta
231 
232  // Get system solver
233  const GroupXML_t& invParam = getInvParams();
234  std::istringstream xml(invParam.xml);
235  XMLReader paramtop(xml);
237  invMdagM(TheMdagMFermSystemSolverFactory::Instance().createObject(
238  invParam.id,paramtop, invParam.path, state, M_prec));
239 
240  // Solve MdagM_prec X = eta
241  SystemSolverResults_t res = (*invMdagM)(phi_tmp, eta_tmp);
242  (*M_prec)(getPhi(i), phi_tmp, PLUS); // (Now get phi = M_prec (M_prec^{-1}\phi)
243  QDPIO::cout<<"TwoFlavRatioConvConvMultihasenWilson4DMonomial: resetting Predictor at end of field refresh"<<std::endl;
244  getMDSolutionPredictor().reset();
245  XMLWriter& xml_out = TheXMLLogWriter::Instance();
246  std::string field_refrs = "FieldRefreshment_"+std::to_string(i);
247  std::string n_count = "n_count_"+std::to_string(i);
248  push(xml_out, field_refrs);
249  write(xml_out, n_count, res.n_count);
250  pop(xml_out);
251  }
252  END_CODE();
253  }
254 
255  virtual void setInternalFields(const Monomial<P, Q>& m)
256  {
257  START_CODE();
258  try{
261  for(int i=0; i<numHasenTerms; ++i)
262  getPhi(i) = fm.getPhi(i);
263  }catch(std::bad_cast){
264  QDPIO::cerr<<"Failed to cast input Monomial to PrecConstDetTwoFlavorRatioConvConvMultihasenWilsonTypeFermMonomial"
265  <<std::endl;
266  QDP_abort(1);
267  }
268  END_CODE();
269  }
270 
272  getMDSolutionPredictor().reset();
273  }
274 
275  int getNumHasenTerms() const {
276  return numHasenTerms;
277  }
278 
279  protected:
280  // override base class getPhi()
281  virtual const T& getPhi(void) const {};
282  virtual T& getPhi(void) {};
283  // pesudo-fermion field for each Hasenbusch term
284  virtual T& getPhi(int i) {
285  return phi[i];
286  }
287  virtual const T& getPhi(int i) const {
288  return phi[i];
289  }
290 
291  const FAType<T,P,Q>& getFermAct()const{
292  return *fermact;
293  }
294 
295  //! Get parameters for the inverter
296  const GroupXML_t& getInvParams() const {
297  return invParam;
298  }
299 
301  return *chrono_predictor;
302  }
303  private:
304  // Hide empty constructor and =
307 
308  // Pseudofermion field phi for multi-hasenbusch term
309  multi1d<T> phi;
310 
312 
313  // Shifted mass mu
314  multi1d<Real> mu;
315 
316  // Number of Hasenbusch terms
318 
319  // The parameters for the inversion
321 
323  };
324 
325 
326  template<typename T, typename P, typename Q,
327  template<typename, typename, typename> class FAType,
328  template<typename, typename, typename> class LOType>
332  {
333  START_CODE();
334  QDPIO::cout << "Constructor: " << __func__ << std::endl;
335 
336  if( param.fermactInv.invParam.id == "NULL" ) {
337  QDPIO::cerr << "Fermact inverter params are NULL" << std::endl;
338  QDP_abort(1);
339  }
340 
341  invParam = param.fermactInv.invParam;
342 
343  // Fermion action (with original seoprec action)
344  {
345  std::istringstream is(param.fermactInv.fermact.xml);
346  XMLReader fermact_reader(is);
347  QDPIO::cout << "Construct fermion action= " << param.fermactInv.fermact.id << std::endl;
348 
349  WilsonTypeFermAct<T,P,Q>* tmp_act =
351  fermact_reader,
352  param.fermactInv.fermact.path);
353 
354  FAType<T,P,Q>* downcast=dynamic_cast<FAType<T,P,Q>* >(tmp_act);
355 
356  // Check success of the downcast
357  if( downcast == 0x0 )
358  {
359  QDPIO::cerr << __func__ << ": unable to downcast FermAct" << std::endl;
360  QDP_abort(1);
361  }
362  fermact = downcast;
363  }
364 
365  // Number of Hasenbusch term
366  numHasenTerms = param.numHasenTerms;
367 
368  // Shifted mass
369  mu.resize(numHasenTerms+1);
370  for(int i=0; i< numHasenTerms+1; ++i){
371  mu[i] = param.mu[i];
372  }
373 
374  // Pseudofermion field phi
375  phi.resize(numHasenTerms);
376  for(int i=0; i<numHasenTerms; ++i)
377  phi[i] = zero;
378 
379  // Get Chronological predictor
380  {
382  if( param.predictor.xml == "" ) {
383  // No predictor specified use zero guess
385  }else {
386  try {
387  std::istringstream chrono_is(param.predictor.xml);
388  XMLReader chrono_xml(chrono_is);
390  chrono_xml,
391  param.predictor.path);
392  }catch(const std::string& e ) {
393  QDPIO::cerr << "Caught Exception Reading XML: " << e << std::endl;
394  QDP_abort(1);
395  }
396  }
397  if( tmp == 0x0 ) {
398  QDPIO::cerr << "Failed to create the 4D ChronoPredictor" << std::endl;
399  QDP_abort(1);
400  }
401  chrono_predictor = tmp;
402  }
403 
404  QDPIO::cout << "Finished constructing: " << __func__ << std::endl;
405  END_CODE();
406  }
407 
408 } //end namespace chroma
409 #endif
Monomials - gauge action or fermion binlinear contributions for HMC.
Primary include file for CHROMA library code.
Monomial factories.
Abstract interface for a Chronological Solution predictor.
Abstract field state.
Definition: field_state.h:27
Differentiable Linear Operator.
Definition: linearop.h:98
virtual void deriv(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
Apply the derivative of the operator onto a source std::vector.
Definition: linearop.h:108
Fermionic monomials (binlinears in fermion fields)
Definition: abs_monomial.h:243
Class for counted reference semantics.
Definition: handle.h:33
An abstract monomial class, for inexact algorithms.
Definition: abs_monomial.h:43
void operator=(const PrecConstDetTwoFlavorRatioConvConvMultihasenWilsonTypeFermMonomial &)
const FAType< T, P, Q > & getFermAct() const
Get at fermion action for pseudofermion field i.
virtual void dsdq(P &F, const AbsFieldState< P, Q > &s)
Compute dsdq for the system... Not specified how to actually do this.
virtual void refreshInternalFields(const AbsFieldState< P, Q > &s)
Refresh pseudofermions.
static T & Instance()
Definition: singleton.h:432
Wilson-like fermion actions.
Definition: fermact.orig.h:344
Zero initial guess predictor.
int mu
Definition: cool.cc:24
Even-odd const determinant Wilson-like fermact.
Even-odd const determinant Wilson-like fermact.
Fermion action factories.
All Wilson-type fermion actions.
Field state.
Helper function for calculating forces.
void write(XMLWriter &xml, const std::string &path, const AsqtadFermActParams &param)
Writer parameters.
void reset()
Reset the default gauge field state.
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
Nd
Definition: meslate.cc:74
LatticeReal phi
Definition: mesq.cc:27
Monomial factories.
multi1d< LatticeColorMatrix > P
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
gaussian(aux)
int n_count
Definition: invbicg.cc:78
LinOpSysSolverMGProtoClover::Q Q
LatticeFermion tmp
Definition: mespbg5p_w.cc:36
push(xml_out,"Condensates")
LinOpSysSolverMGProtoClover::T T
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
::std::string string
Definition: gtest.h:1979
Symmetric even-odd const determinant Wilson-like fermact.
Symmetric even-odd const determinant Wilson-like fermact.
Hold group xml and type id.
Holds return info from SystemSolver call.
Definition: syssolver.h:17
Factory for producing system solvers for MdagM*psi = chi.
multi1d< LatticeColorMatrix > P
Definition: t_clover.cc:13
Two flavor Monomials - gauge action or fermion binlinear contributions for HMC.
Two-flavor RatioConvConv monomial params.
Zero initial guess predictor.
static INTERNAL_PRECISION F