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;