10 template<
typename AFIELD>
15 template<
typename AFIELD>
20 vout.
detailed(m_vl,
"%s: being setup.\n", class_name.c_str());
22 int nin = m_fopr->field_nin();
23 int nvol = m_fopr->field_nvol();
24 int nex = m_fopr->field_nex();
25 vout.
detailed(m_vl,
" Field size: Nin = %d Nvol = %d Nex = %d\n",
28 m_r.reset(nin, nvol, nex);
29 m_x.reset(nin, nvol, nex);
30 m_p.reset(nin, nvol, nex);
31 m_s.reset(nin, nvol, nex);
32 m_v.reset(nin, nvol, nex);
33 m_t.reset(nin, nvol, nex);
34 m_rh.reset(nin, nvol, nex);
38 m_Omega_tolerance = 0.7;
40 m_initial_mode = InitialGuess::RHS;
42 vout.
detailed(m_vl,
"%s: setup finished.\n", class_name.c_str());
47 template<
typename AFIELD>
56 template<
typename AFIELD>
59 const string str_vlevel = params.
get_string(
"verbose_level");
66 double Omega_tolerance;
69 err += params.
fetch_int(
"maximum_number_of_iteration", Niter);
70 err += params.
fetch_int(
"maximum_number_of_restart", Nrestart);
71 err += params.
fetch_double(
"convergence_criterion_squared", Stop_cond);
74 vout.
crucial(m_vl,
"Error at %s: input parameter not found.\n",
78 err = params.
fetch_double(
"Omega_tolerance", Omega_tolerance);
80 Omega_tolerance = 0.7;
85 int Niter2 = Niter * Nrestart;
86 set_parameters(Niter2, Stop_cond, InitialGuess::RHS);
87 set_parameters_BiCGStab_series(Omega_tolerance);
92 template<
typename AFIELD>
96 set_parameters(Niter, Stop_cond, InitialGuess::RHS);
101 template<
typename AFIELD>
104 const InitialGuess init_guess_mode)
110 m_Stop_cond = Stop_cond;
111 std::string prec =
"double";
112 if (
sizeof(
real_t) == 4) prec =
"float";
113 m_initial_mode = init_guess_mode;
116 vout.
general(m_vl,
" Precision: %s\n", prec.c_str());
118 vout.
general(m_vl,
" Stop_cond = %16.8e\n", m_Stop_cond);
119 vout.
general(m_vl,
" init_guess_mode: %d\n", m_initial_mode);
124 template<
typename AFIELD>
130 vout.
general(m_vl,
" Omega_tolerance = %8.2e\n", Omega_tolerance);
136 m_Omega_tolerance = Omega_tolerance;
141 template<
typename AFIELD>
145 vout.
paranoiac(m_vl,
"%s: solver start:\n", class_name.c_str());
153 real_t snorm2 = sqrt(snorm);
157 real_t alpha_prev, rho_prev, omega_prev;
160 if (m_initial_mode == InitialGuess::RHS) {
162 vout.
detailed(m_vl,
"%s: initial_mode = RHS\n", class_name.c_str());
163 #ifdef DEBUG_BICGSTAB
164 double s2 = m_s.norm2();
166 vout.
detailed(m_vl,
"%s: m_x: %d %d %d\n", class_name.c_str(), m_x.nin(), m_x.nvol(), m_x.nex());
167 vout.
detailed(m_vl,
"%s: m_s: %d %d %d: nrom2=%23.16e\n", class_name.c_str(), m_s.nin(), m_s.nvol(), m_s.nex(), s2);
171 }
else if (m_initial_mode == InitialGuess::GIVEN) {
172 vout.
detailed(m_vl,
"%s: initial_mode = GIVEN\n", class_name.c_str());
175 }
else if (m_initial_mode == InitialGuess::ZERO) {
176 vout.
detailed(m_vl,
"%s: initial_mode = ZERO\n", class_name.c_str());
178 vout.
crucial(
"%s: unkown init guess mode\n", class_name.c_str());
185 solve_init(b, rr, alpha_prev, rho_prev, omega_prev, m_initial_mode);
188 for (
int iter = 0; iter < m_Niter; ++iter) {
190 solve_step(rr, iflg, alpha_prev, rho_prev, omega_prev);
191 #ifdef DEBUG_BICGSTAB
193 m_fopr->mult(xq, m_x);
197 double r2 = xq.
norm2();
198 vout.
detailed(m_vl,
" iter=%d, alg_rr=%22.15e, actual r2=%22.15e\n", iter, rr, r2);
204 solve_init(b, rr, alpha_prev, rho_prev, omega_prev, InitialGuess::GIVEN);
209 if (rr < m_Stop_cond) {
210 nconv = 2 * (iter + 1);
216 if ((m_Stop_cond < 0) || (Nconv < 0)) {
217 vout.
detailed(m_vl,
" truncating with iter= %d\n", 2 * m_Niter);
235 m_fopr->mult(m_s, xq);
243 Nconv = nconv + m_init_mult;
244 diff = sqrt(diff2 / sr);
251 template<
typename AFIELD>
257 if (init_mode == InitialGuess::ZERO) {
262 m_fopr->mult(m_v, m_x);
270 #ifdef DEBUG_BICGSTAB
272 double x2 = m_x.norm2();
273 double v2 = m_v.norm2();
274 vout.
general(m_vl,
"%s: x2=%23.15e\n", class_name.c_str(), x2);
275 vout.
general(m_vl,
"%s: v2=%23.15e\n", class_name.c_str(), v2);
293 template<
typename AFIELD>
298 if (fabs(rho) < m_ecrit) {
300 vout.
detailed(m_vl,
"too small value of rho = %e\n", rho);
303 real_t bet = rho * alpha_prev / (rho_prev * omega_prev);
304 #ifdef DEBUG_BICGSTAB
305 vout.
general(m_vl,
"%s: rho = %23.15e\n", class_name.c_str(), rho);
306 vout.
general(m_vl,
"%s: alpha_prev = %23.15e\n", class_name.c_str(), alpha_prev);
307 vout.
general(m_vl,
"%s: rho_prev = %23.15e\n", class_name.c_str(), rho_prev);
308 vout.
general(m_vl,
"%s: omega_prev = %23.15e\n", class_name.c_str(), omega_prev);
309 vout.
general(m_vl,
"%s: bet = %23.15e\n", class_name.c_str(), bet);
313 axpy(m_p, -omega_prev, m_v);
316 m_fopr->mult(m_v, m_p);
319 #ifdef DEBUG_BICGSTAB
321 double p2 = m_p.norm2();
322 double v2 = m_v.norm2();
323 vout.
general(m_vl,
"%s: p2=%23.15e\n", class_name.c_str(), p2);
324 vout.
general(m_vl,
"%s: v2=%23.15e\n", class_name.c_str(), v2);
325 vout.
general(m_vl,
"%s: aden=%23.15e\n", class_name.c_str(), aden);
329 if (fabs(aden) < m_ecrit) {
331 vout.
detailed(m_vl,
"too small denominator aden = %e\n", aden);
334 real_t alpha = rho / aden;
341 axpy(m_s, -alpha, m_v);
343 m_fopr->mult(m_t, m_s);
346 real_t omega_d = m_t.norm2();
347 real_t s_norm2 = m_s.norm2();
348 #ifdef DEBUG_BICGSTAB
349 vout.
general(m_vl,
"%s: alpha = %23.15e\n", class_name.c_str(), alpha);
350 vout.
general(m_vl,
"%s: omega_n = %23.15e\n", class_name.c_str(), omega_n);
351 vout.
general(m_vl,
"%s: omega_d = %23.15e\n", class_name.c_str(), omega_d);
352 vout.
general(m_vl,
"%s: s_norm2 = %23.15e\n", class_name.c_str(), s_norm2);
354 if (fabs(omega_d) < m_ecrit) {
356 vout.
detailed(m_vl,
"too small denominator omega_d = %e\n", omega_d);
359 real_t omega = omega_n / omega_d;
360 real_t abs_rho = abs(omega_n) / sqrt(omega_d * s_norm2);
361 #ifdef DEBUG_BICGSTAB
362 vout.
general(m_vl,
"%s: omega =%23.15e\n", class_name.c_str(), omega);
363 vout.
general(m_vl,
"%s: abs_rho=%23.15e\n", class_name.c_str(), abs_rho);
365 if (abs_rho < m_Omega_tolerance) {
366 vout.
detailed(m_vl,
"Omega_prescription: abs_rho = %23.16e, omega= %23.16e\n", abs_rho, omega);
367 omega *= m_Omega_tolerance / abs_rho;
369 axpy(m_x, omega, m_s);
370 axpy(m_x, alpha, m_p);
373 axpy(m_r, -omega, m_t);
376 #ifdef DEBUG_BICGSTAB
377 vout.
general(m_vl,
"%s: rr = %23.15e\n", class_name.c_str(), rr);
386 template<
typename AFIELD>
389 int Nin = m_fopr->field_nin();
390 int Nvol = m_fopr->field_nvol();
391 int Nex = m_fopr->field_nex();
394 int ninit = m_init_mult;
396 double flop_field =
static_cast<double>(Nin * Nvol * Nex) * NPE;
397 double flop_vector = (6 + ninit * 4 + m_nconv * 11) * flop_field;
398 double flop_fopr = (1 + ninit + m_nconv) * m_fopr->flop_count();
400 if (m_initial_mode == InitialGuess::ZERO) {
401 flop_vector -= m_init_mult * 2 * flop_field;
403 double flop = flop_vector + flop_fopr;