CHROMA
syssolver_mdagm_mr.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! \file
3  * \brief Solve a MdagM*psi=chi linear system by MR
4  */
5 
6 #ifndef __syssolver_mdagm_mr_h__
7 #define __syssolver_mdagm_mr_h__
8 
9 #include "handle.h"
10 #include "syssolver.h"
11 #include "linearop.h"
12 #include "lmdagm.h"
16 
17 namespace Chroma
18 {
19 
20  //! MR system solver namespace
21  namespace MdagMSysSolverMREnv
22  {
23  //! Register the syssolver
24  bool registerAll();
25  }
26 
27 
28  //! Solve a MR system. Here, the operator is NOT assumed to be hermitian
29  /*! \ingroup invert
30  */
31  template<typename T>
33  {
34  public:
35  //! Constructor
36  /*!
37  * \param M_ Linear operator ( Read )
38  * \param invParam inverter parameters ( Read )
39  */
41  const SysSolverMRParams& invParam_) :
42  A(A_), invParam(invParam_)
43  {}
44 
45  //! Destructor is automatic
47 
48  //! Return the subset on which the operator acts
49  const Subset& subset() const {return A->subset();}
50 
51  //! Solver the linear system
52  /*!
53  * \param psi solution ( Modify )
54  * \param chi source ( Read )
55  * \return syssolver results
56  */
58  {
59  START_CODE();
60  StopWatch swatch;
61  SystemSolverResults_t res1,res2; // initialized by a constructor
62  T tmp;
63 
64  swatch.reset(); swatch.start();
66  res2 = InvMR(*A, tmp, psi, invParam.RsdMR, invParam.MaxMR,PLUS);
67 
68  res2.n_count += res1.n_count;
69  { // Find true residuum
70  tmp=zero;
71  T re=zero;
72  (*A)(tmp, psi, PLUS);
73  (*A)(re,tmp, MINUS);
74  re[A->subset()] -= chi;
75  res2.resid = sqrt(norm2(re,A->subset()));
76  }
77 
78  swatch.stop();
79  QDPIO::cout << "MR_SOLVER: " << res2.n_count
80  << " iterations. Rsd = " << res2.resid
81  << " Relative Rsd = " << res2.resid/sqrt(norm2(chi,A->subset())) << std::endl;
82 
83  double time = swatch.getTimeInSeconds();
84  QDPIO::cout << "MR_SOLVER_TIME: "<<time<< " sec" << std::endl;
85 
86  END_CODE();
87 
88  return res;
89  }
90 
91 
92  //! Solver the linear system
93  /*!
94  * \param psi solution ( Modify )
95  * \param chi source ( Read )
96  * \return syssolver results
97  */
99  AbsChronologicalPredictor4D<T>& predictor) const
100  {
101  START_CODE();
102  StopWatch swatch;
103  SystemSolverResults_t res1,res2; // initialized by a constructor
104  T tmp=zero;
105 
106  swatch.reset(); swatch.start();
107 
108  try {
109  AbsTwoStepChronologicalPredictor4D<T>& two_step_predictor =
110  dynamic_cast<AbsTwoStepChronologicalPredictor4D<T>&>(predictor);
111 
112  two_step_predictor.predictY(tmp, *A, chi);
113 
114  res1 = InvMR(*A, chi, tmp, invParam.RsdMR, invParam.MaxMR,MINUS);
115 
116  two_step_predictor.newYVector(tmp);
117 
118  two_step_predictor.predictX(psi, *A, tmp);
119 
120  res2 = InvMR(*A, tmp, psi, invParam.RsdMR, invParam.MaxMR,PLUS);
121 
122  two_step_predictor.newXVector(psi);
123 
124 
125  }
126  catch(std::bad_cast) {
127  T Y ;
129  predictor(psi, (*MdagM), chi);
130  (*A)(Y, psi, PLUS); // Y = M X
131  res1 = InvMR(*A, chi, tmp, invParam.RsdMR, invParam.MaxMR,MINUS);
132  res2 = InvMR(*A, tmp, psi, invParam.RsdMR, invParam.MaxMR,PLUS);
133  predictor.newVector(psi);
134  }
135 
136  res2.n_count += res1.n_count;
137 
138  { // Find true residuum
139  tmp=zero;
140  T re=zero;
141  (*A)(tmp, psi, PLUS);
142  (*A)(re,tmp, MINUS);
143  re[A->subset()] -= chi;
144  res2.resid = sqrt(norm2(re,A->subset()));
145  }
146 
147  swatch.stop();
148  QDPIO::cout << "MR_SOLVER: " << res2.n_count
149  << " iterations. Rsd = " << res2.resid
150  << " Relative Rsd = " << res2.resid/sqrt(norm2(chi,A->subset())) << std::endl;
151 
152  double time = swatch.getTimeInSeconds();
153  QDPIO::cout << "MR_SOLVER_TIME: "<<time<< " sec" << std::endl;
154 
155  END_CODE();
156 
157  return res;
158  }
159 
160 
161  private:
162  // Hide default constructor
164 
167  };
168 
169 
170 } // End namespace
171 
172 #endif
173 
Abstract interface for a Chronological Solution predictor.
virtual void newVector(const T &psi)=0
Abstract interface for a Chronological Solution predictor.
virtual void predictY(T &Y, const T &chi, const Subset &s) const
virtual void newYVector(const T &Y)=0
virtual void predictX(T &X, const T &chi, const Subset &s) const
virtual void newXVector(const T &X)=0
Class for counted reference semantics.
Definition: handle.h:33
Linear Operator.
Definition: linearop.h:27
M^dag.M linear operator.
Definition: lmdagm.h:22
Solve a MR system. Here, the operator is NOT assumed to be hermitian.
Handle< LinearOperator< T > > A
~MdagMSysSolverMR()
Destructor is automatic.
SystemSolverResults_t operator()(T &psi, const T &chi) const
Solver the linear system.
MdagMSysSolverMR(Handle< LinearOperator< T > > A_, const SysSolverMRParams &invParam_)
Constructor.
const Subset & subset() const
Return the subset on which the operator acts.
SystemSolver disambiguator.
SystemSolverResults_t InvMR(const LinearOperator< LatticeFermion > &M, const LatticeFermion &chi, LatticeFermion &psi, const Real &MRovpar, const Real &RsdMR, int MaxMR, enum PlusMinus isign)
Minimal-residual (MR) algorithm for a generic Linear Operator.
Definition: invmr.cc:185
Class for counted reference semantics.
Minimal-Residual (MR) for a generic fermion Linear Operator.
Linear Operators.
M^dag*M composition of a linear operator.
bool registerAll()
Register all the factories.
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
LatticeFermion tmp
Definition: mespbg5p_w.cc:36
LinOpSysSolverMGProtoClover::T T
@ MINUS
Definition: chromabase.h:45
@ PLUS
Definition: chromabase.h:45
multi1d< LatticeFermion > chi(Ncb)
LatticeFermion psi
Definition: mespbg5p_w.cc:35
START_CODE()
Double zero
Definition: invbicg.cc:106
Params for MR inverter.
Holds return info from SystemSolver call.
Definition: syssolver.h:17
Linear system solvers.
Disambiguator for MdagM system solvers.
Handle< LinearOperator< T > > MdagM
Solve a MR system.