Bridge++  Ver. 1.2.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
shiftsolver_CG.cpp
Go to the documentation of this file.
1 
14 #include "shiftsolver_CG.h"
15 
16 //- parameter entries
17 namespace {
18  void append_entry(Parameters& param)
19  {
20  param.Register_int("maximum_number_of_iteration", 0);
21  param.Register_double("convergence_criterion_squared", 0.0);
22 
23  param.Register_string("verbose_level", "NULL");
24  }
25 }
26 //- end
27 
28 //- parameters class
30 //- end
31 
32 const std::string Shiftsolver_CG::class_name = "Shiftsolver_CG";
33 
34 //====================================================================
36 {
37  const string str_vlevel = params.get_string("verbose_level");
38 
39  m_vl = vout.set_verbose_level(str_vlevel);
40 
41  //- fetch and check input parameters
42  int Niter;
43  double Stop_cond;
44 
45  int err = 0;
46  err += params.fetch_int("maximum_number_of_iteration", Niter);
47  err += params.fetch_double("convergence_criterion_squared", Stop_cond);
48 
49  if (err) {
50  vout.crucial(m_vl, "%s: fetch error, input parameter not found.\n", class_name.c_str());
51  abort();
52  }
53 
54 
55  set_parameters(Niter, Stop_cond);
56 }
57 
58 
59 //====================================================================
60 void Shiftsolver_CG::set_parameters(const int Niter, const double Stop_cond)
61 {
62  //- print input parameters
63  vout.general(m_vl, "Parameters of %s:\n", class_name.c_str());
64  vout.general(m_vl, " Niter = %d\n", Niter);
65  vout.general(m_vl, " Stop_cond = %16.8e\n", Stop_cond);
66 
67  //- range check
68  int err = 0;
69  err += ParameterCheck::non_negative(Niter);
70  err += ParameterCheck::square_non_zero(Stop_cond);
71 
72  if (err) {
73  vout.crucial(m_vl, "%s: parameter range check failed.\n", class_name.c_str());
74  abort();
75  }
76 
77  //- store values
78  m_Niter = Niter;
79  m_Stop_cond = Stop_cond;
80 }
81 
82 
83 //====================================================================
84 void Shiftsolver_CG::solve(std::valarray<Field>& xq,
85  std::valarray<double> sigma,
86  const Field& b,
87  int& Nconv, double& diff)
88 {
89  vout.paranoiac(m_vl, " Shift CG solver start.\n");
90 
91  int Nshift = sigma.size();
92 
93  vout.paranoiac(m_vl, " number of shift = %d\n", Nshift);
94  vout.paranoiac(m_vl, " values of shift:\n");
95  for (int i = 0; i < Nshift; ++i) {
96  vout.paranoiac(m_vl, " %d %12.8f\n", i, sigma[i]);
97  }
98 
99  snorm = 1.0 / b.norm2();
100 
101  Nconv = -1;
102 
103  int Nin = b.nin();
104  int Nvol = b.nvol();
105  int Nex = b.nex();
106 
107  p.resize(Nshift);
108  x.resize(Nshift);
109  zeta1.resize(Nshift);
110  zeta2.resize(Nshift);
111  csh2.resize(Nshift);
112  pp.resize(Nshift);
113 
114  for (int i = 0; i < Nshift; ++i) {
115  p[i].reset(Nin, Nvol, Nex);
116  x[i].reset(Nin, Nvol, Nex);
117  zeta1[i] = 1.0;
118  zeta2[i] = 1.0;
119  csh2[i] = sigma[i] - sigma[0];
120  }
121  s.reset(Nin, Nvol, Nex);
122  r.reset(Nin, Nvol, Nex);
123  s = b;
124  r = b;
125 
126  double rr;
127  Nshift2 = Nshift;
128 
129  solve_init(rr);
130 
131  vout.detailed(m_vl, " iter: %8d %22.15e\n", 0, rr * snorm);
132 
133  for (int iter = 0; iter < m_Niter; iter++) {
134  solve_step(rr, sigma);
135 
136  vout.detailed(m_vl, " iter: %8d %22.15e %4d\n", (iter + 1), rr * snorm, Nshift2);
137 
138  if (rr * snorm < m_Stop_cond) {
139  Nconv = iter;
140  break;
141  }
142  }
143  if (Nconv == -1) {
144  vout.crucial(m_vl, "Shiftsolver_CG not converged.\n");
145  abort();
146  }
147 
148 
149  diff = -1.0;
150  for (int i = 0; i < Nshift; ++i) {
151  s = m_fopr->mult(x[i]);
152  s += sigma[i] * x[i];
153  s -= b;
154  double diff1 = s * s;
155  diff1 = sqrt(diff1 * snorm);
156 
157  vout.paranoiac(m_vl, " %4d %22.15e\n", i, diff1);
158 
159  if (diff1 > diff) diff = diff1;
160  }
161 
162  vout.paranoiac(m_vl, " diff(max) = %22.15e \n", diff);
163 
164  for (int i = 0; i < Nshift; ++i) {
165  xq[i] = x[i];
166  }
167 }
168 
169 
170 //====================================================================
172 {
173  int Nshift = p.size();
174 
175  vout.paranoiac(m_vl, "number of shift = %d\n", Nshift);
176 
177  for (int i = 0; i < Nshift; ++i) {
178  p[i] = s;
179  x[i] = 0.0;
180  }
181 
182  r = s;
183  rr = r * r;
184  alpha_p = 0.0;
185  beta_p = 1.0;
186 }
187 
188 
189 //====================================================================
191  const std::valarray<double>& sigma)
192 {
193  s = m_fopr->mult(p[0]);
194  s += sigma[0] * p[0];
195 
196  double rr_p = rr;
197  double pa_p = s * p[0];
198  double beta = -rr_p / pa_p;
199 
200  x[0] -= beta * p[0];
201  r += beta * s;
202  rr = r * r;
203 
204  double alpha = rr / rr_p;
205 
206  p[0] *= alpha;
207  p[0] += r;
208 
209  pp[0] = rr;
210 
211  double alpha_h = 1.0 + alpha_p * beta / beta_p;
212  for (int ish = 1; ish < Nshift2; ++ish) {
213  double zeta = (alpha_h - csh2[ish] * beta) / zeta1[ish]
214  + (1.0 - alpha_h) / zeta2[ish];
215  zeta = 1.0 / zeta;
216  double zr = zeta / zeta1[ish];
217  double beta_s = beta * zr;
218  double alpha_s = alpha * zr * zr;
219 
220  x[ish] -= beta_s * p[ish];
221  p[ish] *= alpha_s;
222  p[ish] += zeta * r;
223 
224  pp[ish] = p[ish] * p[ish];
225  pp[ish] *= snorm;
226 
227  zeta2[ish] = zeta1[ish];
228  zeta1[ish] = zeta;
229  }
230 
231  for (int ish = Nshift2 - 1; ish >= 0; --ish) {
232  vout.paranoiac(m_vl, "%4d %16.8e\n", ish, pp[ish]);
233 
234  if (pp[ish] > m_Stop_cond) {
235  Nshift2 = ish + 1;
236  break;
237  }
238  }
239 
240  alpha_p = alpha;
241  beta_p = beta;
242 }
243 
244 
245 //====================================================================
246 //============================================================END=====
BridgeIO vout
Definition: bridgeIO.cpp:207
void detailed(const char *format,...)
Definition: bridgeIO.cpp:50
void Register_string(const string &, const string &)
Definition: parameters.cpp:352
double norm2() const
Definition: field.cpp:469
static const std::string class_name
virtual const Field mult(const Field &)=0
multiplies fermion operator to a given field and returns the resultant field.
void solve_init(double &)
std::valarray< Field > p
void general(const char *format,...)
Definition: bridgeIO.cpp:38
void Register_int(const string &, const int)
Definition: parameters.cpp:331
Container of Field-type object.
Definition: field.h:37
int nvol() const
Definition: field.h:101
void set_parameters(const Parameters &params)
void solve_step(double &, const std::valarray< double > &)
Class for parameters.
Definition: parameters.h:40
std::valarray< double > pp
int square_non_zero(const double v)
Definition: checker.cpp:41
int nin() const
Definition: field.h:100
std::valarray< Field > x
void reset(const int Nin, const int Nvol, const int Nex, const element_type cmpl=COMPLEX)
Definition: field.h:82
int nex() const
Definition: field.h:102
void paranoiac(const char *format,...)
Definition: bridgeIO.cpp:62
void crucial(const char *format,...)
Definition: bridgeIO.cpp:26
void solve(std::valarray< Field > &solution, std::valarray< double > shift, const Field &source, int &Nconv, double &diff)
std::valarray< double > zeta1
std::valarray< double > zeta2
int non_negative(const int v)
Definition: checker.cpp:21
void Register_double(const string &, const double)
Definition: parameters.cpp:324
int fetch_double(const string &key, double &val) const
Definition: parameters.cpp:124
string get_string(const string &key) const
Definition: parameters.cpp:85
Bridge::VerboseLevel m_vl
Definition: shiftsolver.h:47
int fetch_int(const string &key, int &val) const
Definition: parameters.cpp:141
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:191
std::valarray< double > csh2