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;