10 template<
typename AFIELD>
 
   12   = 
"ASolver_BiCGStab_Cmplx";
 
   15 #ifndef AFIELD_HAS_SUB 
   16   template<
typename AFIELD>
 
   23 #ifndef AFIELD_HAS_DOTC_AND_NORM2 
   24   template<
typename AFIELD>
 
   38 template<
typename AFIELD>
 
   43   vout.
detailed(m_vl, 
"%s: being setup.\n", class_name.c_str());
 
   45   int nin  = m_fopr->field_nin();
 
   46   int nvol = m_fopr->field_nvol();
 
   47   int nex  = m_fopr->field_nex();
 
   49   m_r.reset(nin, nvol, nex);
 
   50   m_p.reset(nin, nvol, nex);
 
   51   m_v.reset(nin, nvol, nex);
 
   52   m_t.reset(nin, nvol, nex);
 
   53   m_rh.reset(nin, nvol, nex);
 
   57   m_Omega_tolerance = 0.7;
 
   59   vout.
detailed(m_vl, 
"%s: setup finished.\n", class_name.c_str());
 
   64 template<
typename AFIELD>
 
   73 template<
typename AFIELD>
 
   76   const string str_vlevel = params.
get_string(
"verbose_level");
 
   83   double       Omega_tolerance;
 
   86   err += params.
fetch_int(
"maximum_number_of_iteration", Niter);
 
   87   err += params.
fetch_int(
"maximum_number_of_restart", Nrestart);
 
   88   err += params.
fetch_double(
"convergence_criterion_squared", Stop_cond);
 
   91     vout.
crucial(m_vl, 
"Error at %s: input parameter not found.\n",
 
   95   err = params.
fetch_double(
"Omega_tolerance", Omega_tolerance);
 
   97     Omega_tolerance = 0.7;
 
   99   std::string initial_guess_str;
 
  100   err           = params.
fetch_string(
"initial_guess_mode", initial_guess_str);
 
  101   initial_guess = InitialGuess::RHS;
 
  104                   class_name.c_str(), initial_guess_str.c_str());
 
  106     if (initial_guess_str == 
"ZERO") {
 
  107       initial_guess = InitialGuess::ZERO;
 
  108     } 
else if (initial_guess_str == 
"GIVEN") {
 
  109       initial_guess = InitialGuess::GIVEN;
 
  111       vout.
crucial(m_vl, 
"%s: unknown initial guess mode string: %d\n",
 
  112                    class_name.c_str(), initial_guess_str.c_str());
 
  118   int Niter2 = Niter * Nrestart;
 
  123   set_parameters(Niter2, Stop_cond, initial_guess);
 
  124   set_parameters_BiCGStab_series(Omega_tolerance);
 
  129 template<
typename AFIELD>
 
  133   set_parameters(Niter, Stop_cond, InitialGuess::RHS);
 
  138 template<
typename AFIELD>
 
  141                                                     const InitialGuess init_guess_mode)
 
  146   m_Stop_cond = Stop_cond;
 
  147   std::string prec = 
"double";
 
  148   if (
sizeof(
real_t) == 4) prec = 
"float";
 
  149   m_initial_mode = init_guess_mode;
 
  152   vout.
general(m_vl, 
"  Precision: %s\n", prec.c_str());
 
  154   vout.
general(m_vl, 
"  Stop_cond = %16.8e\n", m_Stop_cond);
 
  155   vout.
general(m_vl, 
"  init_guess_mode: %d\n", m_initial_mode);
 
  160 template<
typename AFIELD>
 
  166   vout.
general(m_vl, 
"  Omega_tolerance = %8.2e\n", Omega_tolerance);
 
  172   m_Omega_tolerance = Omega_tolerance;
 
  177 template<
typename AFIELD>
 
  181   vout.
paranoiac(m_vl, 
"%s: solver start:\n", class_name.c_str());
 
  190   real_t snorm     = sqrt(snorm2);
 
  193   scal(m_t, snorm_inv);
 
  205   solve_init(m_t, rr, coeff, snorm_inv, m_initial_mode);
 
  208   for (
int iter = 0; iter < m_Niter; ++iter) {
 
  210     solve_step(rr, iflg, coeff);
 
  214       scal(m_t, snorm_inv);
 
  215       solve_init_GIVEN(m_t, rr, coeff, 
real_t(1.0));
 
  216       vout.
detailed(m_vl, 
"%s: restarted.\n", class_name.c_str());
 
  220     if (rr < m_Stop_cond) {
 
  221       nconv = 2 * (iter + 1);  
 
  226     if ((m_Stop_cond < 0) || (Nconv < 0)) {
 
  227       vout.
detailed(m_vl, 
"  truncating with iter= %d\n", 2 * m_Niter);
 
  233                    m_Niter, rr * snorm2);
 
  243   m_fopr->mult(m_t, xq);
 
  251   Nconv = nconv + m_init_mult; 
 
  252   diff  = sqrt(diff2 / snorm2);
 
  259 template<
typename AFIELD>
 
  266   if (init_mode == InitialGuess::RHS) {
 
  267     solve_init_RHS(b, rr, prev);
 
  268   } 
else if (init_mode == InitialGuess::GIVEN) {
 
  269     solve_init_GIVEN(b, rr, prev, scale);
 
  270   } 
else if (init_mode == InitialGuess::ZERO) {
 
  271     solve_init_ZERO(b, rr, prev);
 
  273     vout.
crucial(
"%s: unkown init guess mode\n", class_name.c_str());
 
  280 template<
typename AFIELD>
 
  291     vout.
detailed(m_vl, 
"  |m_x|^2 = %23.16e [init_RHS]\n", temp);
 
  294   m_fopr->mult(m_v, m_x);
 
  299     vout.
detailed(m_vl, 
"  |m_v|^2 = %23.16e [init_RHS]\n", temp);
 
  311   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx   rr      = %23.16e [init_RHS]\n", rr);
 
  322 template<
typename AFIELD>
 
  329   if (scale != 
real_t(1.0)) {
 
  333   m_fopr->mult(m_v, m_x);
 
  349   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  rr      = %23.16e [init_GIVEN]\n", rr);
 
  354 template<
typename AFIELD>
 
  371   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  rr      = %23.16e [init_ZERO]\n", rr);
 
  376 template<
typename AFIELD>
 
  380   const real_t Omega_tolerance = m_Omega_tolerance;
 
  384 #ifdef DEBUG_BICGSTAB_CMPLX 
  385   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  rho     = %23.16e %23.16e\n", real(rho), imag(rho));
 
  387   if (abs(rho) < m_ecrit) {
 
  389     vout.
detailed(m_vl, 
"too small value of rho = %23.16e %23.16e\n", real(rho), imag(rho));
 
  391     double r2  = 
norm2(m_r);
 
  392     double rh2 = 
norm2(m_rh);
 
  404   m_fopr->mult(m_v, m_p);
 
  407 #ifdef DEBUG_BICGSTAB_CMPLX 
  408   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  bet     = %23.16e %23.16e\n", real(bet), imag(bet));
 
  409   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  aden    = %23.16e %23.16e\n", real(aden), imag(aden));
 
  411   if (abs(aden) < m_ecrit) {
 
  413     vout.
detailed(m_vl, 
"too small denominator  aden = %23.16e %23.16e\n", real(aden), imag(aden));
 
  417 #ifdef DEBUG_BICGSTAB_CMPLX 
  418   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  alpha   = %23.16e %23.16e\n", real(alpha), imag(alpha));
 
  422   axpy(m_r, -alpha, m_v);
 
  423   m_fopr->mult(m_t, m_r);
 
  435   const double abs_rho = abs(omega_n) / sqrt(omega_d * s_norm2);
 
  437 #ifdef DEBUG_BICGSTAB_CMPLX 
  438   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  omega_n = %23.16e %23.16e\n", real(omega_n), imag(omega_n));
 
  439   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  omega_d = %23.16e\n", omega_d);
 
  440   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  omega   = %23.16e %23.16e\n", real(omega), imag(omega));
 
  441   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  s_norm2 = %23.16e\n", s_norm2);
 
  442   vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  abs_rho = %23.16e\n", abs_rho);
 
  447   if (abs_rho < Omega_tolerance) {
 
  448     vout.
detailed(m_vl, 
"ASolver_BiCGStab_Cmplx  abs_rho = %23.16e,  omega   = %23.16e %23.16e  [Omega presciption applied]\n", abs_rho, real(omega), imag(omega));
 
  449     omega *= Omega_tolerance / abs_rho;
 
  453   axpy(m_x, omega, m_r);
 
  454   axpy(m_x, alpha, m_p);
 
  457   axpy(m_r, -omega, m_t);
 
  467 template<
typename AFIELD>
 
  470   int Nin  = m_fopr->field_nin();
 
  471   int Nvol = m_fopr->field_nvol();
 
  472   int Nex  = m_fopr->field_nex();
 
  478   double flop_field  = 
static_cast<double>(Nin * Nvol * Nex) * NPE;
 
  479   double flop_vector = (6 + 4 * ninit + iter * 20) * flop_field;
 
  481   double flop_fopr = (1 + ninit + iter) * m_fopr->flop_count();
 
  483   if (m_initial_mode == InitialGuess::ZERO) {
 
  484     flop_vector -= (2 * ninit) * flop_field;
 
  485     flop_fopr   -= m_fopr->flop_count();
 
  488   double flop = flop_vector + flop_fopr;