CHROMA
syssolver_mdagm_rel_ibicgstab_clover.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! \file
3  * \brief Solve a MdagM*psi=chi linear system by IBiCGStab
4  */
5 
6 #ifndef __syssolver_mdagm_rel_ibicgstab_multiprec_h__
7 #define __syssolver_mdagm_rel_ibicgstab_multiprec_h__
8 #include "chroma_config.h"
9 
10 #include "handle.h"
11 #include "state.h"
12 #include "syssolver.h"
13 #include "linearop.h"
14 #include "lmdagm.h"
22 
23 #include <string>
24 
25 namespace Chroma
26 {
27 
28  //! Richardson system solver namespace
29  namespace MdagMSysSolverReliableIBiCGStabCloverEnv
30  {
31  //! Register the syssolver
32  bool registerAll();
33  }
34 
35 
36 
37  //! Solve a system using Richardson iteration.
38  /*! \ingroup invert
39  *** WARNING THIS SOLVER WORKS FOR CLOVER FERMIONS ONLY ***
40  */
41 
43  {
44  public:
45  typedef LatticeFermion T;
46  typedef LatticeColorMatrix U;
47  typedef multi1d<LatticeColorMatrix> Q;
48 
49  typedef LatticeFermionF TF;
50  typedef LatticeColorMatrixF UF;
51  typedef multi1d<LatticeColorMatrixF> QF;
52 
53  typedef LatticeFermionD TD;
54  typedef LatticeColorMatrixD UD;
55  typedef multi1d<LatticeColorMatrixD> QD;
56 
57  //! Constructor
58  /*!
59  * \param M_ Linear operator ( Read )
60  * \param invParam inverter parameters ( Read )
61  */
63  Handle< FermState<T,Q,Q> > state_,
64  const SysSolverReliableBiCGStabCloverParams& invParam_) :
65  A(A_), invParam(invParam_)
66  {
67 
68  // Get the Links out of the state and convertto single.
69  QF links_single; links_single.resize(Nd);
70  QD links_double; links_double.resize(Nd);
71 
72  const Q& links = state_->getLinks();
73  for(int mu=0; mu < Nd; mu++) {
74  links_single[mu] = links[mu];
75  links_double[mu] = links[mu];
76  }
77 
78 
79  // Links single hold the possibly stouted links
80  // with gaugeBCs applied...
81  // Now I need to create a single prec state...
82  fstate_single = new PeriodicFermState<TF,QF,QF>(links_single);
83  fstate_double = new PeriodicFermState<TD,QD,QD>(links_double);
84 
85  // Make single precision M
88 
89 
90 
91  }
92 
93  //! Destructor is automatic
95 
96  //! Return the subset on which the operator acts
97  const Subset& subset() const {return A->subset();}
98 
99  //! Solver the linear system
100  /*!
101  * \param psi solution ( Modify )
102  * \param chi source ( Read )
103  * \return syssolver results
104  */
106  {
107  SystemSolverResults_t res,res1,res2;
108 
109  START_CODE();
110  StopWatch swatch;
111  swatch.start();
112  const Subset& s = (*M_double).subset();
113 
114 
115  // Boo Hiss, we can't downcast to a two step predictor.
116  // We rely on the fact that we can predict
117  // X ~ (M^\dagger M)^{-1} chi
118  // and then
119  // X ~ M^{-1} M^{-\dagger} chi
120  //
121  // Then MX ~ M^{-\dagger} chi ~ Y
122 
123  T Y ;
125  (*A)(Y, psi, PLUS); // Y = M X
126 
127  TD psi_d;
128  TD chi_d;
129  psi_d[s] = Y;
130  chi_d[s] = chi;
131  // Two Step IBiCGStab:
132  // Step 1: M^\dagger Y = chi;
133 
135  *M_single,
136  chi_d,
137  psi_d,
139  invParam.Delta,
141  MINUS);
142 
143  chi_d[s] = psi;
144 
146  *M_single,
147  psi_d,
148  chi_d,
150  invParam.Delta,
152  PLUS);
153 
154  psi[s] = chi_d;
155 
156  // Check solution
157  {
158  T r;
159  r[A->subset()]=chi;
160  T tmp,tmp2;
161  // M^\dag M
162  (*A)(tmp, psi, PLUS);
163  (*A)(tmp2,tmp, MINUS);
164  r[A->subset()] -= tmp2;
165  res.n_count = res1.n_count + res2.n_count;
166  res.resid = sqrt(norm2(r, A->subset()));
167  }
168  QDPIO::cout << "RELIABLE_IBICGSTAB_SOLVER: " << res.n_count
169  << " iterations. Rsd = " << res.resid
170  << " Relative Rsd = " << res.resid/sqrt(norm2(chi,A->subset())) << std::endl;
171 
172  swatch.stop();
173  double time = swatch.getTimeInSeconds();
174  QDPIO::cout << "RELIABLE_IBICGSTAB_SOLVER_TIME: "<<time<< " sec" << std::endl;
175 
176 
177  END_CODE();
178  return res;
179 
180  }
181 
182 
183  //! Solver the linear system
184  /*!
185  * \param psi solution ( Modify )
186  * \param chi source ( Read )
187  * \return syssolver results
188  */
190  AbsChronologicalPredictor4D<T>& predictor) const
191  {
192  SystemSolverResults_t res,res1,res2;
193 
194  START_CODE();
195  StopWatch swatch;
196  swatch.start();
197  const Subset& s = (*M_double).subset();
198 
199  TD psi_d; TD chi_d;
200  try {
201  // Get a two step solution plan
202  AbsTwoStepChronologicalPredictor4D<T>& two_step_predictor
203  = dynamic_cast<AbsTwoStepChronologicalPredictor4D<T>& >(predictor);
204 
205  // Hooray , we succeeded.
206  // Step 1: Solve M^\dagger Y = chi
207  T Y = zero;
208  two_step_predictor.predictY(Y,*A,chi);
209  psi_d[s] = Y;
210  chi_d[s] = chi;
211  // Two Step IBiCGStab:
212  // Step 1: M^\dagger Y = chi;
213 
215  *M_single,
216  chi_d,
217  psi_d,
219  invParam.Delta,
221  MINUS);
222 
223  Y[s] = psi_d;
224  two_step_predictor.newYVector(Y);
225 
227 
228  two_step_predictor.predictX(psi,*MdagM, chi);
229  chi_d[s] = psi;
230 
232  *M_single,
233  psi_d,
234  chi_d,
236  invParam.Delta,
238  PLUS);
239 
240 
241  psi[s] = chi_d;
242  two_step_predictor.newXVector(psi);
243  }
244  catch(std::bad_cast) {
245 
246  // Boo Hiss, we can't downcast to a two step predictor.
247  // We rely on the fact that we can predict
248  // X ~ (M^\dagger M)^{-1} chi
249  // and then
250  // X ~ M^{-1} M^{-\dagger} chi
251  //
252  // Then MX ~ M^{-\dagger} chi ~ Y
253 
254  T Y ;
256  predictor(psi, (*MdagM), chi);
257  (*A)(Y, psi, PLUS); // Y = M X
258 
259  psi_d[s] = Y;
260  chi_d[s] = chi;
261  // Two Step IBiCGStab:
262  // Step 1: M^\dagger Y = chi;
263 
265  *M_single,
266  chi_d,
267  psi_d,
269  invParam.Delta,
271  MINUS);
272 
273  chi_d[s] = psi;
274 
276  *M_single,
277  psi_d,
278  chi_d,
280  invParam.Delta,
282  PLUS);
283 
284  psi[s] = chi_d;
285  predictor.newVector(psi);
286 
287 
288  }
289 
290  // Check solution
291  {
292  T r;
293  r[A->subset()]=chi;
294  T tmp,tmp2;
295  // M^\dag M
296  (*A)(tmp, psi, PLUS);
297  (*A)(tmp2,tmp, MINUS);
298  r[A->subset()] -= tmp2;
299  res.n_count = res1.n_count + res2.n_count;
300  res.resid = sqrt(norm2(r, A->subset()));
301  }
302  QDPIO::cout << "RELIABLE_IBICGSTAB_SOLVER: " << res.n_count
303  << " iterations. Rsd = " << res.resid
304  << " Relative Rsd = " << res.resid/sqrt(norm2(chi,A->subset())) << std::endl;
305 
306  swatch.stop();
307  double time = swatch.getTimeInSeconds();
308  QDPIO::cout << "RELIABLE_IBICGSTAB_SOLVER_TIME: "<<time<< " sec" << std::endl;
309 
310 
311  END_CODE();
312  return res;
313  }
314 
315 
316  private:
317  // Hide default constructor
321 
322  // Created and initialized here.
327  };
328 
329 
330 } // End namespace
331 
332 #endif
333 
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
Even-odd preconditioned Clover-Dirac operator.
Even-odd preconditioned Clover-Dirac operator.
Support class for fermion actions and linear operators.
Definition: state.h:94
Class for counted reference semantics.
Definition: handle.h:33
Linear Operator.
Definition: linearop.h:27
M^dag.M linear operator.
Definition: lmdagm.h:22
SystemSolverResults_t operator()(T &psi, const T &chi) const
Solver the linear system.
MdagMSysSolverReliableIBiCGStabClover(Handle< LinearOperator< T > > A_, Handle< FermState< T, Q, Q > > state_, const SysSolverReliableBiCGStabCloverParams &invParam_)
Constructor.
const Subset & subset() const
Return the subset on which the operator acts.
SystemSolver disambiguator.
Periodic version of FermState.
Parameters for Clover fermion action.
int mu
Definition: cool.cc:24
Even-odd preconditioned Clover fermion linear operator.
SystemSolverResults_t InvIBiCGStabReliable(const LinearOperator< LatticeFermionF > &A, const LatticeFermionF &chi, LatticeFermionF &psi, const Real &RsdBiCGStab, const Real &Delta, int MaxBiCGStab, enum PlusMinus isign)
Bi-CG stabilized.
Class for counted reference semantics.
Linear Operators.
M^dag*M composition of a linear operator.
Nd
Definition: meslate.cc:74
Double tmp2
Definition: mesq.cc:30
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
LatticeFermion tmp
Definition: mespbg5p_w.cc:36
@ 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
multi1d< LatticeFermion > s(Ncb)
Periodic ferm state and a creator.
BiCGStab Solver with reliable updates.
Support class for fermion actions and linear operators.
Holds return info from SystemSolver call.
Definition: syssolver.h:17
Linear system solvers.
Disambiguator for MdagM system solvers.
Handle< LinearOperator< T > > MdagM
Factory for producing system solvers for MdagM*psi = chi.