Bridge++  Ver. 1.1.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
solver_BiCGStab.cpp
Go to the documentation of this file.
1 
14 #include "solver_BiCGStab.h"
15 
16 #ifdef USE_PARAMETERS_FACTORY
17 #include "parameters_factory.h"
18 #endif
19 
20 #ifdef USE_FACTORY
21 namespace {
22  Solver *create_object(Fopr *fopr)
23  {
24  return new Solver_BiCGStab(fopr);
25  }
26 
27 
28  bool init = Solver::Factory::Register("BiCGStab", create_object);
29 }
30 #endif
31 
32 //- parameter entries
33 namespace {
34  void append_entry(Parameters& param)
35  {
36  param.Register_int("maximum_number_of_iteration", 0);
37  param.Register_double("convergence_criterion_squared", 0.0);
38 
39  param.Register_string("verbose_level", "NULL");
40  }
41 
42 
43 #ifdef USE_PARAMETERS_FACTORY
44  bool init_param = ParametersFactory::Register("Solver.BiCGStab", append_entry);
45 #endif
46 }
47 //- end
48 
49 //- parameters class
51 //- end
52 
53 //====================================================================
55 {
56  const string str_vlevel = params.get_string("verbose_level");
57 
58  m_vl = vout.set_verbose_level(str_vlevel);
59 
60  //- fetch and check input parameters
61  int Niter;
62  double Stop_cond;
63 
64  int err = 0;
65  err += params.fetch_int("maximum_number_of_iteration", Niter);
66  err += params.fetch_double("convergence_criterion_squared", Stop_cond);
67 
68  if (err) {
69  vout.crucial(m_vl, "Solver_BiCGStab: fetch error, input parameter not found.\n");
70  abort();
71  }
72 
73 
74  set_parameters(Niter, Stop_cond);
75 }
76 
77 
78 //====================================================================
79 void Solver_BiCGStab::set_parameters(const int Niter, const double Stop_cond)
80 {
81  //- print input parameters
82  vout.general(m_vl, "Parameters of Solver_BiCGStab:\n");
83  vout.general(m_vl, " Niter = %d\n", Niter);
84  vout.general(m_vl, " Stop_cond = %16.8e\n", Stop_cond);
85 
86  //- range check
87  int err = 0;
88  err += ParameterCheck::non_negative(Niter);
89  err += ParameterCheck::square_non_zero(Stop_cond);
90 
91  if (err) {
92  vout.crucial(m_vl, "Solver_BiCGStab: parameter range check failed.\n");
93  abort();
94  }
95 
96  //- store values
97  m_Niter = Niter;
98  m_Stop_cond = Stop_cond;
99 }
100 
101 
102 //====================================================================
103 void Solver_BiCGStab::solve(Field& xq, const Field& b,
104  int& Nconv, double& diff)
105 {
106  vout.paranoiac(m_vl, " BiCGStab solver starts\n");
107 
108  reset_field(b);
109 
110  vout.paranoiac(m_vl, " norm of b = %16.8e\n", b.norm2());
111  vout.paranoiac(m_vl, " size of b = %d\n", b.size());
112 
113  double snorm = 1.0 / b.norm2();
114  double rr;
115 
116  Nconv = -1;
117  s = b;
118 
119  solve_init(b, rr);
120 
121  vout.detailed(m_vl, " iter: %8d %22.15e\n", 0, rr * snorm);
122 
123  for (int iter = 0; iter < m_Niter; iter++) {
124  solve_step(rr);
125 
126  vout.detailed(m_vl, " iter: %8d %22.15e\n", 2 * (iter + 1), rr * snorm);
127 
128  if (rr * snorm < m_Stop_cond) {
129  s = m_fopr->mult(x);
130  s -= b;
131  diff = s.norm();
132 
133  if (diff * diff * snorm < m_Stop_cond) {
134  Nconv = 2 * (iter + 1);
135  break;
136  }
137 
138  s = x;
139  solve_init(b, rr);
140  }
141  }
142  if (Nconv == -1) {
143  vout.crucial(m_vl, "BiCGStab solver not converged.\n");
144  abort();
145  }
146 
147  p = m_fopr->mult(x);
148  p -= b;
149  diff = p.norm();
150 
151  xq = x;
152 }
153 
154 
155 //====================================================================
157 {
158  int Nin = b.nin();
159  int Nvol = b.nvol();
160  int Nex = b.nex();
161 
162  if ((s.nin() != Nin) || (s.nvol() != Nvol) || (s.nex() != Nex)) {
163  s.reset(Nin, Nvol, Nex);
164  r.reset(Nin, Nvol, Nex);
165  x.reset(Nin, Nvol, Nex);
166  p.reset(Nin, Nvol, Nex);
167  v.reset(Nin, Nvol, Nex);
168  rh.reset(Nin, Nvol, Nex);
169 
170  vout.paranoiac(m_vl, " Solver_BiCGStab: field size reset.\n");
171  }
172 }
173 
174 
175 //====================================================================
176 void Solver_BiCGStab::solve_init(const Field& b, double& rr)
177 {
178  v = m_fopr->mult(s);
179  r = b;
180  x = s;
181  r -= v;
182  rh = r;
183  rr = r * r;
184 
185  rho_p = 1.0;
186  alpha_p = 1.0;
187  omega_p = 1.0;
188 
189  p = 0.0;
190  v = 0.0;
191 }
192 
193 
194 //====================================================================
196 {
197  double rho = rh * r;
198  double bet = rho * alpha_p / (rho_p * omega_p);
199 
200  p = r + bet * (p - omega_p * v);
201 
202  v = m_fopr->mult(p);
203  double aden = rh * v;
204  double alpha = rho / aden;
205 
206  s = r - (alpha * v);
207 
208  Field t(s);
209  t = m_fopr->mult(s);
210 
211  double omega_n = t * s;
212  double omega_d = t * t;
213  double omega = omega_n / omega_d;
214 
215  x += omega * s + alpha * p;
216  r = s - omega * t;
217 
218  rho_p = rho;
219  alpha_p = alpha;
220  omega_p = omega;
221 
222  rr = r * r;
223 }
224 
225 
226 //====================================================================
227 //============================================================END=====