19 template<
typename AFIELD>
21 =
"ASolver_FBiCGStab";
23 template<
typename AFIELD>
28 int nin = m_fopr->field_nin();
29 int nvol = m_fopr->field_nvol();
30 int nex = m_fopr->field_nex();
32 m_r.reset(nin, nvol, nex);
33 m_x.reset(nin, nvol, nex);
34 m_p.reset(nin, nvol, nex);
35 m_s.reset(nin, nvol, nex);
36 m_v.reset(nin, nvol, nex);
37 m_t.reset(nin, nvol, nex);
38 m_rh.reset(nin, nvol, nex);
39 m_u.reset(nin, nvol, nex);
42 m_Omega_tolerance = 0.7;
47 template<
typename AFIELD>
56 template<
typename AFIELD>
60 const string str_vlevel = params.
get_string(
"verbose_level");
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",
79 double Omega_tolerance;
80 err = params.
fetch_double(
"Omega_tolerance", Omega_tolerance);
82 Omega_tolerance = 0.7;
86 int Niter2 = Niter * Nrestart;
89 set_parameters_BiCGStab_series(Omega_tolerance);
94 template<
typename AFIELD>
102 m_Stop_cond = Stop_cond;
103 m_initial_mode = init_guess_mode;
104 std::string prec =
"double";
105 if (
sizeof(
real_t) == 4) prec =
"float";
108 vout.
general(m_vl,
" Precision: %s\n", prec.c_str());
110 vout.
general(m_vl,
" Stop_cond = %16.8e\n", m_Stop_cond);
111 vout.
general(m_vl,
" InitialGuess = %d\n", m_initial_mode);
116 template<
typename AFIELD>
120 set_parameters(Niter, Stop_cond, InitialGuess::RHS);
125 template<
typename AFIELD>
128 const bool use_init_guess)
131 if (use_init_guess) {
132 set_parameters(Niter, Stop_cond, InitialGuess::GIVEN);
134 set_parameters(Niter, Stop_cond, InitialGuess::RHS);
140 template<
typename AFIELD>
146 vout.
general(m_vl,
" Omega_tolerance = %8.2e\n", Omega_tolerance);
152 m_Omega_tolerance = Omega_tolerance;
157 template<
typename AFIELD>
162 vout.
paranoiac(m_vl,
"%s: solver start.\n", class_name.c_str());
165 real_t bnorm2, bnorm, bnorm_inv, bnorm2_inv;
173 if (!(bnorm2 > 0.0)) {
177 bnorm = sqrt(bnorm2);
178 bnorm_inv =
real_t(1.0) / bnorm;
179 bnorm2_inv =
real_t(1.0) / bnorm2;
181 m_prec->reset_flop_count();
185 solve_init(b, xq, rr, prev);
186 vout.
detailed(m_vl,
" FBiCGStab init: %22.15e\n", rr * bnorm2_inv);
190 for (
int iter = 0; iter < m_Niter; ++iter) {
191 solve_step1(rr, prev);
196 flop = flop_count_intermediate(iter2);
198 vout.
detailed(m_vl,
"FBiCGStab %d %22.15e Flop(double+float) %e\n", iter2, rr * bnorm2_inv, flop);
199 if (rr * bnorm2_inv < m_Stop_cond) {
203 solve_step2(rr, prev);
207 flop = flop_count_intermediate(iter2);
209 vout.
detailed(m_vl,
"FBiCGStab %d %22.15e Flop(double+float) %e\n", iter2, rr * bnorm2_inv, flop);
210 if (rr * bnorm2_inv < m_Stop_cond) {
230 m_fopr->mult(m_s, xq);
233 vout.
general(m_vl,
"FBiCGStab nconv = %d, diff2 = %22.15e\n", nconv, diff2 * bnorm2_inv);
240 diff = sqrt(diff2 * bnorm2_inv);
247 template<
typename AFIELD>
254 if (m_initial_mode == InitialGuess::RHS) {
257 m_fopr->mult(m_v, m_x);
259 }
else if (m_initial_mode == InitialGuess::GIVEN) {
262 m_fopr->mult(m_v, m_x);
264 }
else if (m_initial_mode == InitialGuess::ZERO) {
268 vout.
crucial(
"%s: unkown init guess mode\n", class_name.c_str());
283 vout.
detailed(m_vl,
"ASolver_FBiCGStab rr = %23.16e [init]\n", rr);
288 template<
typename AFIELD>
293 m_prec->mult(m_u, m_p);
294 m_fopr->mult(m_v, m_u);
300 axpy(m_r, -alpha, m_v);
301 axpy(m_x, alpha, m_u);
304 #ifdef DEBUG_FBICGSTAB
305 vout.
detailed(m_vl,
"ASolver_FBiCGStab alpha_d = %23.16e %23.16e\n", real(alpha_d), std::imag(alpha_d));
306 vout.
detailed(m_vl,
"ASolver_FBiCGStab alpha = %23.16e %23.16e\n", real(alpha), std::imag(alpha));
307 vout.
detailed(m_vl,
"ASolver_FBiCGStab rr = %23.16e\n", rr);
313 template<
typename AFIELD>
317 m_prec->mult(m_u, m_r);
318 m_fopr->mult(m_t, m_u);
326 const real_t Omega_tolerance = m_Omega_tolerance;
327 const real_t abs_rho = abs(omega_n) / sqrt(omega_d * r_norm2);
329 #ifdef DEBUG_FBICGSTAB
330 vout.
detailed(m_vl,
"ASolver_FBiCGStab omega_n = %23.16e %23.16e\n", real(omega_n), std::imag(omega_n));
331 vout.
detailed(m_vl,
"ASolver_FBiCGStab omega_d = %23.16e\n", omega_d);
332 vout.
detailed(m_vl,
"ASolver_FBiCGStab omega = %23.16e %23.16e\n", real(omega), std::imag(omega));
333 vout.
detailed(m_vl,
"ASolver_FBiCGStab r_norm2 = %23.16e\n", r_norm2);
334 vout.
detailed(m_vl,
"ASolver_FBiCGStab abs_rho = %23.16e\n", abs_rho);
338 if (abs_rho < Omega_tolerance) {
339 omega *= Omega_tolerance / abs_rho;
340 vout.
detailed(m_vl,
"ASolver_FBiCGStab omega = %23.16e %23.16e [Omega presciption applied]\n", real(omega), std::imag(omega));
343 axpy(m_x, omega, m_u);
344 axpy(m_r, -omega, m_t);
351 axpy(m_p, -omega, m_v);
352 aypx(beta, m_p, m_r);
355 #ifdef DEBUG_FBICGSTAB
356 vout.
detailed(m_vl,
"ASolver_FBiCGStab rho = %23.16e %23.16e\n", real(rho), std::imag(rho));
357 vout.
detailed(m_vl,
"ASolver_FBiCGStab beta = %23.16e %23.16e\n", real(beta), std::imag(beta));
358 vout.
detailed(m_vl,
"ASolver_FBiCGStab rr = %23.16e\n", rr);
364 template<
typename AFIELD>
372 template<
typename AFIELD>
375 return flop_count_intermediate(m_nconv);
380 template<
typename AFIELD>
383 int Nin = m_fopr->field_nin();
384 int Nvol = m_fopr->field_nvol();
385 int Nex = m_fopr->field_nex();
390 double flop_field =
static_cast<double>(Nin * Nvol * Nex) * NPE;
393 double flop_vector = (6 + ninit * 4 + (iter / 2) * 42) * flop_field;
395 flop_vector += 14 * flop_field;
398 double flop_fopr = (1 + ninit + iter) * m_fopr->flop_count();
399 double flop_prec = m_prec->flop_count();
401 double flop = flop_vector + flop_fopr + flop_prec;