16 #ifdef USE_FACTORY_AUTOREGISTER
18 bool init = Solver_BiCGStab_IDS_L_Cmplx::register_factory();
36 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);
57 set_parameters(Niter, Nrestart, Stop_cond, use_init_guess, Omega_tolerance, N_L, Tol_L);
115 vout.
general(
m_vl,
" use_init_guess = %s\n", use_init_guess ?
"true" :
"false");
178 const double Stop_cond,
179 const bool use_init_guess,
180 const double Omega_tolerance,
191 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) {
387 dcomplex c_Rayleigh_prev = cmplx(0.0, 0.0);
389 bool is_converged_L =
false;
393 if (!is_converged_L) {
397 dcomplex beta = alpha_prev2 * (rho / rho_prev2);
401 for (
int i = 0; i < j + 1; ++i) {
409 alpha_prev2 = rho_prev2 / conj(gamma);
411 for (
int i = 0; i < j + 1; ++i) {
423 double r_tmp =
m_r[j].norm2();
424 dcomplex c_Rayleigh =
dotc(
m_r[j],
m_r[j + 1]) / r_tmp;
426 dcomplex c_E = (c_Rayleigh - c_Rayleigh_prev) / c_Rayleigh;
429 c_Rayleigh_prev = c_Rayleigh;
439 is_converged_L =
true;
445 std::vector<double> sigma(
m_N_L + 1);
446 std::vector<dcomplex> gamma_prime(
m_N_L + 1);
449 std::vector<dcomplex> tau(
m_N_L * (
m_N_L + 1));
451 const double sigma_0 =
m_r[0].norm2();
453 for (
int j = 1; j < N_L_tmp + 1; ++j) {
454 for (
int i = 1; i < j; ++i) {
458 tau[ij] = conj(r_ji) / sigma[i];
462 sigma[j] =
m_r[j].norm2();
465 gamma_prime[j] = conj(r_0j) / sigma[j];
468 double abs_rho = abs(r_0j) / sqrt(sigma[j] * sigma_0);
475 std::vector<dcomplex> gamma(
m_N_L + 1);
476 gamma[N_L_tmp] = gamma_prime[N_L_tmp];
478 for (
int j = N_L_tmp - 1; j > 0; --j) {
479 dcomplex c_tmp = cmplx(0.0, 0.0);
481 for (
int i = j + 1; i < N_L_tmp + 1; ++i) {
483 c_tmp += tau[ji] * gamma[i];
486 gamma[j] = gamma_prime[j] - c_tmp;
491 std::vector<dcomplex> gamma_double_prime(
m_N_L);
493 for (
int j = 1; j < N_L_tmp; ++j) {
494 dcomplex c_tmp = cmplx(0.0, 0.0);
496 for (
int i = j + 1; i < N_L_tmp; ++i) {
498 c_tmp += tau[ji] * gamma[i + 1];
501 gamma_double_prime[j] = gamma[j + 1] + c_tmp;
506 axpy(
m_r[0], -gamma_prime[N_L_tmp],
m_r[N_L_tmp]);
509 for (
int j = 1; j < N_L_tmp; ++j) {
548 const int Nin =
m_x.
nin();
550 const int Nex =
m_x.
nex();
559 const double gflop_axpy = (Nin * Nex * 2) * ((Nvol * NPE) / 1.0e+9);
560 const double gflop_dotc = (Nin * Nex * 4) * ((Nvol * NPE) / 1.0e+9);
561 const double gflop_norm = (Nin * Nex * 2) * ((Nvol * NPE) / 1.0e+9);
565 const double gflop_init = gflop_fopr + gflop_axpy + gflop_norm;
566 const double gflop_step_BiCG_part = 2 * N_L_prev_total * gflop_fopr
567 + 3 * N_L_prev_total * gflop_dotc
569 + N_L_prev_total * gflop_norm;
570 const double gflop_step_L_part = (
m_N_L_part_count + N_L_prev_total) * gflop_dotc
573 const double gflop_step = gflop_step_BiCG_part + gflop_step_L_part;
574 const double gflop_true_residual = gflop_fopr + gflop_axpy + gflop_norm;
576 const double gflop = gflop_norm + gflop_init + gflop_step + gflop_true_residual * (
m_Nrestart_count + 1)