CHROMA
inv_gmresr_cg_array.cc
Go to the documentation of this file.
1 #include "chromabase.h"
4 
5 
6 namespace Chroma
7 {
8 
9 template<typename T>
11  const LinearOperatorArray<T>& PrecM,
12  const LinearOperatorArray<T>& UnprecM,
13  const multi1d<T>& b,
14  multi1d<T>& x,
15  const Real& epsilon,
16  const Real& epsilon_prec,
17  int MaxGMRESR,
18  int MaxGMRESRPrec,
19  int& n_count)
20 {
21  START_CODE();
22 
23  const Subset& s= UnprecM.subset();
24  int N5 = UnprecM.size();
25 
26  // Sanity checks
27  if( b.size() != N5 ) {
28  QDPIO::cerr << "b has wrong size in 5th dimension. N5 = " << N5 << " b.size() = " << b.size() << std::endl;
29  }
30 
31  if( x.size() != N5 ) {
32  QDPIO::cerr << "x has wrong size in 5th dimension. N5 = " << N5 << " x.size() = " << x.size() << std::endl;
33  }
34 
35 
36  multi1d<T> r(N5);
37  // x_0 = 0
38  // r_0 = b
39  for(int n5=0; n5 < N5; n5++ ) {
40  x[n5][s] = zero;
41  r[n5][s] = b[n5];
42  }
43 
44  // Arrays of pointers for C and U, up to the maximum number
45  multi1d<multi1d<T>*> C(MaxGMRESR);
46  multi1d<multi1d<T>*> U(MaxGMRESR);
47  int C_size=0;
48 
49  // Get || r ||
50  Double norm_r = sqrt(norm2(r,s));
51  Double terminate = sqrt(norm2(b,s))*epsilon;
52  int iter=0;
53 
54  int prec_count;
55  // Do the loop
56  while( toBool( norm_r > terminate) && iter < MaxGMRESR ) {
57  // First we have to get a new u std::vector (in U)
58  multi1d<T>* u = new multi1d<T>;
59  (*u).resize(N5);
60 
61  /*
62  for(int n5=0; n5 < N5; n5++) {
63  (*u)[n5][s] = zero;
64  }
65  */
66 
67  multi1d<T> tmp(N5);
68  for(int n5=0;n5 < N5; n5++) {
69  (*u)[n5][s]= zero;
70  }
71  // Now solve with the preconditioned system to preconditioned accuracy
72  // THis is done with CG
73  // solve MM u = r
74 
75  PrecM(tmp,r , MINUS);
76  InvCG1(PrecMM, tmp, *u, epsilon_prec, MaxGMRESRPrec, prec_count);
77 
78 
79  // Get C
80  multi1d<T>* c = new multi1d<T>;
81  (*c).resize(N5);
82 
83  // c = A u
84  UnprecM( *c, *u, PLUS);
85 
86 
87  // Now there is some orthogonalisation to do
88  for(int i =0; i < C_size; i++) {
89 
90  // Compute < C[i], c > in 5D
91  Complex beta = Real(0);
92  for(int n5=0; n5 < N5; n5++) {
93  beta += innerProduct( (*(C[i]))[n5], (*c)[n5], s );
94  }
95 
96  // Compute c -= beta*C[i]
97  // u -= beta*U[i]
98  for(int n5=0; n5 < N5; n5++) {
99  (*c)[n5][s] -= beta*(*(C[i]))[n5];
100  (*u)[n5][s] -= beta*(*(U[i]))[n5];
101  }
102  }
103 
104 
105  // norm2 works in 5D
106  Double norm_c = sqrt(norm2( *c, s));
107 
108  // Now normalise c and u
109  for(int n5=0; n5 < N5; n5++) {
110  (*c)[n5][s] /= norm_c;
111  (*u)[n5][s] /= norm_c;
112  }
113  // Hook vectors into the U, C arrays
114  C[C_size] = c;
115  U[C_size] = u;
116  C_size++;
117 
118  Complex alpha = Real(0);
119  for(int n5=0; n5 < N5; n5++ ) {
120  alpha += innerProduct( (*c)[n5], r[n5], s);
121  }
122 
123  for(int n5=0; n5 < N5; n5++) {
124  x[n5][s] += alpha*(*u)[n5];
125  r[n5][s] -= alpha*(*c)[n5];
126  }
127  iter++;
128  norm_r = sqrt(norm2(r,s));
129  QDPIO::cout << "Inv Rel GMRESR: iter "<< iter <<" || r || = " << norm_r << std::endl;
130  }
131 
132  // Cleanup
133  for(int i=0; i < C_size; i++) {
134  delete C[i];
135  delete U[i];
136  }
137 
138  if( iter == MaxGMRESR ) {
139  QDPIO::cout << "Nonconvergence warning " << std::endl;
140  }
141 
142  n_count = iter;
143  END_CODE();
144 }
145 
146 template<>
150  const multi1d<LatticeFermion>& b,
151  multi1d<LatticeFermion>& x,
152  const Real& epsilon,
153  const Real& epsilon_prec,
154  int MaxGMRESR,
155  int MaxGMRESRPrec,
156  int& n_count)
157 {
158  InvGMRESR_CG_a(PrecMM, PrecM, UnprecM, b, x, epsilon, epsilon_prec, MaxGMRESR, MaxGMRESRPrec, n_count);
159 }
160 
161 } // end namespace Chroma
Primary include file for CHROMA library code.
Linear Operator to arrays.
Definition: linearop.h:61
virtual int size() const =0
Expected length of array index.
virtual const Subset & subset() const =0
Return the subset on which the operator acts.
SystemSolverResults_t InvCG1(const LinearOperator< LatticeFermion > &A, const LatticeFermion &chi, LatticeFermion &psi, const Real &RsdCG, int MaxCG, int MinCG)
Conjugate-Gradient (CGNE) algorithm for a generic Linear Operator.
Definition: invcg1.cc:215
Relaxed GMRESR algorithm of the Wuppertal Group.
Conjugate-Gradient algorithm for a generic Linear Operator.
int x
Definition: meslate.cc:34
SpinMatrix C()
C = Gamma(10)
Definition: barspinmat_w.cc:29
int epsilon(int i, int j, int k)
BinaryReturn< C1, C2, FnInnerProduct >::Type_t innerProduct(const QDPSubType< T1, C1 > &s1, const QDPType< T2, C2 > &s2)
static const LatticeInteger & beta(const int dim)
Definition: stag_phases_s.h:47
static const LatticeInteger & alpha(const int dim)
Definition: stag_phases_s.h:43
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
void InvGMRESR_CG_a(const LinearOperatorArray< T > &PrecMM, const LinearOperatorArray< T > &PrecM, const LinearOperatorArray< T > &UnprecM, const multi1d< T > &b, multi1d< T > &x, const Real &epsilon, const Real &epsilon_prec, int MaxGMRESR, int MaxGMRESRPrec, int &n_count)
static multi1d< LatticeColorMatrix > u
void InvGMRESR_CG(const LinearOperatorArray< LatticeFermion > &PrecMM, const LinearOperatorArray< LatticeFermion > &PrecM, const LinearOperatorArray< LatticeFermion > &UnprecM, const multi1d< LatticeFermion > &b, multi1d< LatticeFermion > &x, const Real &epsilon, const Real &epsilon_prec, int MaxGMRESR, int MaxGMRESRPrec, int &n_count)
int n_count
Definition: invbicg.cc:78
LatticeFermion tmp
Definition: mespbg5p_w.cc:36
Double c
Definition: invbicg.cc:108
int i
Definition: pbg5p_w.cc:55
@ MINUS
Definition: chromabase.h:45
@ 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
multi1d< LatticeColorMatrix > U