CHROMA
inv_multiprec_richardson.cc
Go to the documentation of this file.
2 
3 namespace Chroma {
4 
5 
6  /*! This is the multi precision inverter
7  Solves systems via iterative Refinement.
8  The interface specifies explicit single/double precision references
9  These should be set up by the caller.
10  Currently I have made the SyssolverLinOpRichardson and the SyssolverMdagMRichardson
11  do this
12  */
15  const LatticeFermionD& b,
16  LatticeFermionD& x,
17  int MaxIter,
18  Real RsdTarget,
20  {
21  START_CODE();
22 
23 
24  LatticeFermionD r;
25 
26  const Subset& s = D.subset();
27 
28 
29  // Target Residue
30  Double rsd_t = Double(RsdTarget)*Double(RsdTarget)*norm2(b,s);
31 
32  // Compute Initial residue:
33  {
34  LatticeFermionD tmp;
35  D(tmp, x, PLUS);
36  r[s] = b;
37  r[s] -= tmp; // r = b-Ax
38  }
39 
40  Double rnorm = norm2(r, s); // || r ||^2
41  QDPIO::cout << "Initial Norm: " << rnorm << std::endl;
42 
43  if( toBool( rnorm <= rsd_t ) ) {
44 
45  // We are done
46  QDPIO::cout << "Iter 0: || r || = "<< rnorm << " || r_target || = " << rsd_t << std::endl;
47 
48  res.n_count = 0;
49  res.resid = Real(sqrt(rnorm));
50 
51  return;
52  }
53 
54  for(int i=1; i <= MaxIter ; i++) {
55 
56  LatticeFermionD delta_x; // The Richardson Correction
57  LatticeFermionD Ddelta_x; // D delta_x
58 
59  // Compute Delta_x = D^{-1} r
60  LatticeFermionF r_single(r); // Downcast r to single
61  LatticeFermionF dx_single; // Initial guess for dx solve
62 
63 
64 
65  dx_single[s] = zero;
66 
67  Dinv(dx_single, r); // Solve in single
68 
69  delta_x[s] = dx_single; // Upcast back to double
70 
71  D(Ddelta_x, delta_x, PLUS); // Get D delta_x
72 
73 
74  x[s] += delta_x;
75  r[s] -= Ddelta_x;
76 
77  rnorm = norm2(r, s);
78 
79  // Convergence check
80  if( toBool( rnorm <= rsd_t ) ) {
81  // Compute Initial residue:
82  {
83  LatticeFermionD tmp;
84  D(tmp, x, PLUS);
85  r[s] = b;
86  r[s] -= tmp; // r = b-Ax
87  }
88  // We are done
89 
90  res.n_count = i;
91  res.resid = Real(sqrt(norm2(r)/norm2(b)));
92  return;
93  }
94 
95  }
96 
97  QDPIO::cout << "Richardson Multi Prec Solver: NONCONVERGENCE" << std::endl;
98  res.n_count = MaxIter;
99  res.resid = Real(sqrt(rnorm));
100 
101  END_CODE();
102  }
103 
104 
105 
106 
107 }
virtual const Subset & subset() const =0
Return the subset on which the operator acts.
Linear system solvers.
Definition: syssolver.h:34
int x
Definition: meslate.cc:34
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
LatticeFermion tmp
Definition: mespbg5p_w.cc:36
void InvMultiPrecRichardson(const SystemSolver< LatticeFermionF > &Dinv, const LinearOperator< LatticeFermionD > &D, const LatticeFermionD &b, LatticeFermionD &x, int MaxIter, Real RsdTarget, SystemSolverResults_t &res)
int i
Definition: pbg5p_w.cc:55
@ PLUS
Definition: chromabase.h:45
START_CODE()
Complex b
Definition: invbicg.cc:96
Double zero
Definition: invbicg.cc:106
multi1d< LatticeFermion > s(Ncb)
FloatingPoint< double > Double
Definition: gtest.h:7351
Holds return info from SystemSolver call.
Definition: syssolver.h:17