Bridge++  Ver.2.1.3
ashiftsolver_CG-tmpl.h
Go to the documentation of this file.
1 
16 
17 template<typename FIELD, typename FOPR>
19  = "AShiftsolver_CG";
20 
21 //====================================================================
22 template<typename FIELD, typename FOPR>
24 {
26 
27  m_vl = CommonParameters::Vlevel();
28 
29  std::string vlevel;
30  if (!params.fetch_string("verbose_level", vlevel)) {
31  m_vl = vout.set_verbose_level(vlevel);
32  }
33 
34  vout.general(m_vl, "%s: construction\n", class_name.c_str());
36 
37  set_parameters(params);
38 
40  vout.general(m_vl, "%s: construction finished.\n",
41  class_name.c_str());
42 }
43 
44 //====================================================================
45 template<typename FIELD, typename FOPR>
47 {
48  // do nothing
49 }
50 
51 //====================================================================
52 template<typename FIELD, typename FOPR>
54  const Parameters& params)
55 {
56  std::string vlevel;
57  if (!params.fetch_string("verbose_level", vlevel)) {
58  m_vl = vout.set_verbose_level(vlevel);
59  }
60 
61  //- fetch and check input parameters
62  int Nshift, Niter;
63  double Stop_cond;
64 
65  int err = 0;
66  err += params.fetch_int("number_of_shifts", Nshift);
67  err += params.fetch_int("maximum_number_of_iteration", Niter);
68  err += params.fetch_double("convergence_criterion_squared", Stop_cond);
69 
70  if (err) {
71  vout.crucial(m_vl, "Error at %s: input parameter not found.\n",
72  class_name.c_str());
73  exit(EXIT_FAILURE);
74  }
75 
76  set_parameters(Nshift, Niter, Stop_cond);
77 }
78 
79 
80 //====================================================================
81 template<typename FIELD, typename FOPR>
83 {
84  params.set_int("number_of_shifts", m_Nshift);
85  params.set_int("maximum_number_of_iteration", m_Niter);
86  params.set_double("convergence_criterion_squared", m_Stop_cond);
87 
88  params.set_string("verbose_level", vout.get_verbose_level(m_vl));
89 }
90 
91 
92 //====================================================================
93 template<typename FIELD, typename FOPR>
95  const int Nshift,
96  const int Niter,
97  const double Stop_cond)
98 {
99 #pragma omp barrier
100 
101  int ith = ThreadManager::get_thread_id();
102  if(ith == 0){
103  m_Nshift = Nshift;
104  m_Niter = Niter;
105  m_Stop_cond = Stop_cond;
106  }
107 #pragma omp barrier
108 
109  //- range check
110  int err = 0;
111  err += ParameterCheck::non_negative(Nshift);
112  err += ParameterCheck::non_negative(Niter);
113  err += ParameterCheck::square_non_zero(Stop_cond);
114 
115  if (err) {
116  vout.crucial(m_vl, "Error at %s: parameter range check failed.\n",
117  class_name.c_str());
118  exit(EXIT_FAILURE);
119  }
120 
121  //- print input parameters
122  vout.general(m_vl, "%s: parameters:\n", class_name.c_str());
123  vout.general(m_vl, " Nshift = %d\n", m_Nshift);
124  vout.general(m_vl, " Niter = %d\n", m_Niter);
125  vout.general(m_vl, " Stop_cond = %8.2e\n", m_Stop_cond);
126 
127  if(m_Nshift != m_p.size()){
128  reset_field();
129  }
130 
131 }
132 
133 
134 //====================================================================
135 template<typename FIELD, typename FOPR>
137 {
139 
140  vout.crucial("%s: reset_field called.\n", class_name.c_str());
141 
142  int Nin = m_fopr->field_nin();
143  int Nvol = m_fopr->field_nvol();
144  int Nex = m_fopr->field_nex();
145 
146  m_p.resize(m_Nshift);
147  m_x.resize(m_Nshift);
148  m_zeta1.resize(m_Nshift);
149  m_zeta2.resize(m_Nshift);
150  m_csh2.resize(m_Nshift);
151  m_pp.resize(m_Nshift);
152 
153  for (int i = 0; i < m_Nshift; ++i) {
154  m_p[i].reset(Nin, Nvol, Nex);
155  m_x[i].reset(Nin, Nvol, Nex);
156  }
157 
158  m_s.reset(Nin, Nvol, Nex);
159  m_r.reset(Nin, Nvol, Nex);
160 }
161 
162 
163 //====================================================================
164 template<typename FIELD, typename FOPR>
166  std::vector<FIELD>& xq,
167  const std::vector<double>& sigma,
168  const FIELD& b,
169  int& Nconv,
170  double& diff)
171 {
172  if(sigma.size() != m_Nshift){
173  vout.crucial("%s: size of shift values incorrect: %d\n",
174  class_name.c_str(), sigma.size());
175  exit(EXIT_FAILURE);
176  }
177 
178  vout.detailed(m_vl, "Shift CG solver start.\n");
179  vout.paranoiac(m_vl, " number of shift = %d\n", m_Nshift);
180  vout.paranoiac(m_vl, " values of shift:\n");
181  for (int i = 0; i < m_Nshift; ++i) {
182  vout.paranoiac(m_vl, " %8d %12.8f\n", i, sigma[i]);
183  }
184 
185  m_snorm = 1.0 / b.norm2();
186 
187  int Nconv2 = -1;
188 
189  reset_params(sigma);
190 
191  copy(m_s, b);
192  copy(m_r, b);
193 
194  double rr = 0.0;
195 
196  solve_init(rr);
197 
198  vout.detailed(m_vl, " iter: %8d %22.15e\n", 0, rr * m_snorm);
199 
200  bool is_converged = false;
201 
202  for (int iter = 0; iter < m_Niter; iter++) {
203  solve_step(rr);
204 
205  Nconv2 += 1;
206 
207  vout.detailed(m_vl, " iter: %8d %22.15e %4d\n",
208  (iter + 1), rr * m_snorm, m_Nshift2);
209 
210  if (rr * m_snorm < m_Stop_cond) {
211  is_converged = true;
212  break;
213  }
214  }
215 
216  if (!is_converged) {
217  vout.crucial(m_vl, "Error at %s: not converged.\n",
218  class_name.c_str());
219  exit(EXIT_FAILURE);
220  }
221 
222 
223  std::vector<double> diffs(m_Nshift);
224  for (int i = 0; i < m_Nshift; ++i) {
225  diffs[i] = 0.0;
226  }
227 
228  for (int i = 0; i < m_Nshift; ++i) {
229  m_fopr->mult(m_s, m_x[i]);
230  axpy(m_s, sigma[i], m_x[i]);
231  axpy(m_s, -1.0, b);
232 
233  double diff1 = sqrt(m_s.norm2() * m_snorm);
234 
235  vout.paranoiac(m_vl, " %4d %22.15e\n", i, diff1);
236 
237  // if (diff1 > diff2) diff2 = diff1;
238  diffs[i] = diff1;
239  }
240 
241 #pragma omp barrier
242 #pragma omp master
243  {
244  double diff2 = -1.0;
245 
246  for (int i = 0; i < m_Nshift; ++i) {
247  if (diffs[i] > diff2) diff2 = diffs[i];
248  }
249 
250  diff = diff2;
251 
252  Nconv = Nconv2;
253  }
254 #pragma omp barrier
255 
256  for (int i = 0; i < m_Nshift; ++i) {
257  copy(xq[i], m_x[i]);
258  }
259 
260  vout.paranoiac(m_vl, " diff(max) = %22.15e \n", diff);
261 }
262 
263 
264 //====================================================================
265 template<typename FIELD, typename FOPR>
267 {
268  int Nshift = m_p.size();
269 
270  vout.paranoiac(m_vl, "number of shift = %d\n", Nshift);
271 
272  for (int i = 0; i < Nshift; ++i) {
273  copy(m_p[i], m_s);
274  scal(m_x[i], 0.0);
275  }
276 
277  copy(m_r, m_s);
278  rr = m_r.norm2();
279 
280 #pragma omp barrier
281 #pragma omp master
282  {
283  m_alpha_p = 0.0;
284  m_beta_p = 1.0;
285  }
286 #pragma omp barrier
287 }
288 
289 
290 //====================================================================
291 template<typename FIELD, typename FOPR>
293 {
294  m_fopr->mult(m_s, m_p[0]);
295  axpy(m_s, m_sigma0, m_p[0]);
296 
297  double rr_p = rr;
298  double pa_p = dot(m_s, m_p[0]);
299  double beta = -rr_p / pa_p;
300 
301  axpy(m_x[0], -beta, m_p[0]);
302  axpy(m_r, beta, m_s);
303  rr = m_r.norm2();
304 
305  double alpha = rr / rr_p;
306 
307  aypx(alpha, m_p[0], m_r);
308 
309 #pragma omp barrier
310 #pragma omp master
311  {
312  m_pp[0] = rr;
313  }
314 #pragma omp barrier
315 
316  double alpha_h = 1.0 + m_alpha_p * beta / m_beta_p;
317 
318  for (int ish = 1; ish < m_Nshift2; ++ish) {
319  double zeta = (alpha_h - m_csh2[ish] * beta) / m_zeta1[ish]
320  + (1.0 - alpha_h) / m_zeta2[ish];
321  zeta = 1.0 / zeta;
322  double zr = zeta / m_zeta1[ish];
323  double beta_s = beta * zr;
324  double alpha_s = alpha * zr * zr;
325 
326  axpy(m_x[ish], -beta_s, m_p[ish]);
327  scal(m_p[ish], alpha_s);
328  axpy(m_p[ish], zeta, m_r);
329 
330  double ppr = m_p[ish].norm2();
331 
332 #pragma omp barrier
333 #pragma omp master
334  {
335  m_pp[ish] = ppr * m_snorm;
336 
337  m_zeta2[ish] = m_zeta1[ish];
338  m_zeta1[ish] = zeta;
339  }
340 #pragma omp barrier
341  }
342 
343  int ish1 = m_Nshift2;
344 
345  for (int ish = m_Nshift2 - 1; ish >= 0; --ish) {
346  vout.paranoiac(m_vl, "%4d %16.8e\n", ish, m_pp[ish]);
347  if (m_pp[ish] > m_Stop_cond) {
348  ish1 = ish + 1;
349  break;
350  }
351  }
352 
353 #pragma omp barrier
354 #pragma omp master
355  {
356  m_Nshift2 = ish1;
357 
358  m_alpha_p = alpha;
359  m_beta_p = beta;
360  }
361 #pragma omp barrier
362 }
363 
364 
365 //====================================================================
366 template<typename FIELD, typename FOPR>
368  const std::vector<double>& sigma)
369 {
370 #pragma omp barrier
371 
372  int ith = ThreadManager::get_thread_id();
373  if(ith == 0){
374  for (int i = 0; i < m_Nshift; ++i) {
375  m_zeta1[i] = 1.0;
376  m_zeta2[i] = 1.0;
377  m_csh2[i] = sigma[i] - sigma[0];
378  m_pp[i] = 0.0;
379  }
380  m_sigma0 = sigma[0];
381  m_Nshift2 = m_Nshift;
382  }
383 #pragma omp barrier
384 
385 }
386 
387 
388 //====================================================================
389 template<typename FIELD, typename FOPR>
391 {
392  vout.general(m_vl, "Warning at %s: flop_count() not yet implemented.\n",
393  class_name.c_str());
394  return 0.0;
395 }
396 
397 
398 //============================================================END=====
AShiftsolver_CG::get_parameters
void get_parameters(Parameters &params) const
Definition: ashiftsolver_CG-tmpl.h:82
AShiftsolver_CG::reset_params
void reset_params(const std::vector< double > &sigma)
Definition: ashiftsolver_CG-tmpl.h:367
Parameters::set_string
void set_string(const string &key, const string &value)
Definition: parameters.cpp:39
AShiftsolver_CG::set_parameters
void set_parameters(const Parameters &params)
Definition: ashiftsolver_CG-tmpl.h:53
AShiftsolver_CG::reset_field
void reset_field()
Definition: ashiftsolver_CG-tmpl.h:136
Parameters
Class for parameters.
Definition: parameters.h:46
AShiftsolver_CG::solve_init
void solve_init(double &)
Definition: ashiftsolver_CG-tmpl.h:266
Parameters::set_double
void set_double(const string &key, const double value)
Definition: parameters.cpp:33
Bridge::BridgeIO::decrease_indent
void decrease_indent()
Definition: bridgeIO.cpp:518
Bridge::BridgeIO::increase_indent
void increase_indent()
Definition: bridgeIO.cpp:508
Bridge::BridgeIO::detailed
void detailed(const char *format,...)
Definition: bridgeIO.cpp:281
AShiftsolver_CG::tidyup
void tidyup()
Definition: ashiftsolver_CG-tmpl.h:46
aypx
void aypx(const double a, Field &y, const Field &x)
aypx(y, a, x): y := a * y + x
Definition: field.cpp:510
AShiftsolver_CG::solve_step
void solve_step(double &)
Definition: ashiftsolver_CG-tmpl.h:292
axpy
void axpy(Field &y, const double a, const Field &x)
axpy(y, a, x): y := a * x + y
Definition: field.cpp:381
dot
double dot(const Field &y, const Field &x)
Definition: field.cpp:577
ParameterCheck::non_negative
int non_negative(const int v)
Definition: parameterCheck.cpp:21
AShiftsolver_CG::init
void init(const Parameters &params)
Definition: ashiftsolver_CG-tmpl.h:23
copy
void copy(Field &y, const Field &x)
copy(y, x): y = x
Definition: field.cpp:213
AShiftsolver_CG::flop_count
double flop_count()
Definition: ashiftsolver_CG-tmpl.h:390
Bridge::BridgeIO::paranoiac
void paranoiac(const char *format,...)
Definition: bridgeIO.cpp:300
AShiftsolver_CG::solve
void solve(std::vector< FIELD > &solution, const std::vector< double > &shift, const FIELD &source, int &Nconv, double &diff)
Definition: ashiftsolver_CG-tmpl.h:165
ParameterCheck::square_non_zero
int square_non_zero(const double v)
Definition: parameterCheck.cpp:43
threadManager.h
ashiftsolver_CG.h
CommonParameters::Vlevel
static Bridge::VerboseLevel Vlevel()
Definition: commonParameters.h:122
Bridge::BridgeIO::set_verbose_level
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:195
Parameters::set_int
void set_int(const string &key, const int value)
Definition: parameters.cpp:36
scal
void scal(Field &x, const double a)
scal(x, a): x = a * x
Definition: field.cpp:262
Parameters::fetch_string
int fetch_string(const string &key, string &value) const
Definition: parameters.cpp:378
Parameters::fetch_double
int fetch_double(const string &key, double &value) const
Definition: parameters.cpp:327
Bridge::BridgeIO::crucial
void crucial(const char *format,...)
Definition: bridgeIO.cpp:242
ThreadManager::get_thread_id
static int get_thread_id()
returns thread id.
Definition: threadManager.cpp:253
AShiftsolver_CG
Multishift Conjugate Gradient solver.
Definition: ashiftsolver_CG.h:33
Parameters::fetch_int
int fetch_int(const string &key, int &value) const
Definition: parameters.cpp:346
Bridge::BridgeIO::general
void general(const char *format,...)
Definition: bridgeIO.cpp:262
ThreadManager::assert_single_thread
static void assert_single_thread(const std::string &class_name)
assert currently running on single thread.
Definition: threadManager.cpp:372
Bridge::vout
BridgeIO vout
Definition: bridgeIO.cpp:572
Bridge::BridgeIO::get_verbose_level
static std::string get_verbose_level(const VerboseLevel vl)
Definition: bridgeIO.cpp:216