16 #ifdef USE_FACTORY_AUTOREGISTER
18 bool init = Solver_BiCGStab_DS_L_Cmplx::register_factory();
37 double Omega_tolerance;
41 err += params.
fetch_int(
"maximum_number_of_iteration", Niter);
42 err += params.
fetch_int(
"maximum_number_of_restart", Nrestart);
43 err += params.
fetch_double(
"convergence_criterion_squared", Stop_cond);
44 err += params.
fetch_bool(
"use_initial_guess", use_init_guess);
45 err += params.
fetch_double(
"Omega_tolerance", Omega_tolerance);
46 err += params.
fetch_int(
"number_of_orthonormal_vectors", N_L);
47 err += params.
fetch_double(
"tolerance_for_DynamicSelection_of_L", Tol_L);
58 set_parameters(Niter, Nrestart, Stop_cond, use_init_guess, Omega_tolerance, N_L, Tol_L);
116 vout.
general(
m_vl,
" use_init_guess = %s\n", use_init_guess ?
"true" :
"false");
179 const double Stop_cond,
180 const bool use_init_guess,
181 const double Omega_tolerance,
192 vout.
general(
m_vl,
" use_init_guess = %s\n", use_init_guess ?
"true" :
"false");
229 int& Nconv,
double& diff)
231 const double bnorm2 = b.
norm2();
232 const int bsize = b.
size();
238 bool is_converged =
false;
256 Nconv2 += Nconv_unit;
261 for (
int i_restart = 0; i_restart <
m_Nrestart; i_restart++) {
262 for (
int iter = 0; iter <
m_Niter; iter++) {
299 vout.
crucial(
m_vl,
" iter(final): %8d %22.15e\n", Nconv2, diff2 / bnorm2);
309 diff = sqrt(diff2 / bnorm2);
322 const int Nin = b.
nin();
323 const int Nvol = b.
nvol();
324 const int Nex = b.
nex();
336 for (
int i = 0; i <
m_N_L + 1; ++i) {
337 m_u[i].reset(Nin, Nvol, Nex);
338 m_r[i].reset(Nin, Nvol, Nex);
352 for (
int i = 0; i <
m_N_L + 1; ++i) {
386 dcomplex c_Rayleigh_prev = cmplx(0.0, 0.0);
388 bool is_converged_L =
false;
392 if (!is_converged_L) {
396 dcomplex beta = alpha_prev2 * (rho / rho_prev2);
400 for (
int i = 0; i < j + 1; ++i) {
407 alpha_prev2 = rho_prev2 / conj(gamma);
409 for (
int i = 0; i < j + 1; ++i) {
421 double r_tmp =
m_r[j].norm2();
422 dcomplex c_Rayleigh =
dotc(
m_r[j],
m_r[j + 1]) / r_tmp;
424 dcomplex c_E = (c_Rayleigh - c_Rayleigh_prev) / c_Rayleigh;
426 c_Rayleigh_prev = c_Rayleigh;
436 is_converged_L =
true;
442 std::vector<double> sigma(
m_N_L + 1);
443 std::vector<dcomplex> gamma_prime(
m_N_L + 1);
446 std::vector<dcomplex> tau(
m_N_L * (
m_N_L + 1));
448 const double sigma_0 =
m_r[0].norm2();
450 for (
int j = 1; j < N_L_tmp + 1; ++j) {
451 for (
int i = 1; i < j; ++i) {
455 tau[ij] = conj(r_ji) / sigma[i];
459 sigma[j] =
m_r[j].norm2();
462 gamma_prime[j] = conj(r_0j) / sigma[j];
465 double abs_rho = abs(r_0j) / sqrt(sigma[j] * sigma_0);
472 std::vector<dcomplex> gamma(
m_N_L + 1);
473 gamma[N_L_tmp] = gamma_prime[N_L_tmp];
475 for (
int j = N_L_tmp - 1; j > 0; --j) {
476 dcomplex c_tmp = cmplx(0.0, 0.0);
478 for (
int i = j + 1; i < N_L_tmp + 1; ++i) {
480 c_tmp += tau[ji] * gamma[i];
483 gamma[j] = gamma_prime[j] - c_tmp;
488 std::vector<dcomplex> gamma_double_prime(
m_N_L);
490 for (
int j = 1; j < N_L_tmp; ++j) {
491 dcomplex c_tmp = cmplx(0.0, 0.0);
493 for (
int i = j + 1; i < N_L_tmp; ++i) {
495 c_tmp += tau[ji] * gamma[i + 1];
498 gamma_double_prime[j] = gamma[j + 1] + c_tmp;
503 axpy(
m_r[0], -gamma_prime[N_L_tmp],
m_r[N_L_tmp]);
506 for (
int j = 1; j < N_L_tmp; ++j) {
535 const int Nin =
m_x.
nin();
537 const int Nex =
m_x.
nex();
546 const double gflop_axpy = (Nin * Nex * 2) * ((Nvol * NPE) / 1.0e+9);
547 const double gflop_dotc = (Nin * Nex * 4) * ((Nvol * NPE) / 1.0e+9);
548 const double gflop_norm = (Nin * Nex * 2) * ((Nvol * NPE) / 1.0e+9);
552 const double gflop_init = gflop_fopr + gflop_axpy + gflop_norm;
553 const double gflop_step_BiCG_part = 2 * N_L_prev_total * gflop_fopr
554 + 3 * N_L_prev_total * gflop_dotc
556 + N_L_prev_total * gflop_norm;
557 const double gflop_step_L_part = (
m_N_L_part_count + N_L_prev_total) * gflop_dotc
560 const double gflop_step = gflop_step_BiCG_part + gflop_step_L_part;
561 const double gflop_true_residual = gflop_fopr + gflop_axpy + gflop_norm;
563 const double gflop = gflop_norm + gflop_init + gflop_step + gflop_true_residual * (
m_Nrestart_count + 1)