void idata::set_region (int r_pvt,int r_sat, int r_eql, int r_fip) { props->set_i ("pvt_region", r_pvt); props->set_i ("fip_region", r_fip); props->set_i ("sat_region", r_sat); props->set_i ("eql_region", r_eql); // check if (r_pvt <= 0 || r_sat <= 0 || r_eql <= 0 || r_fip <= 0) { bs_throw_exception ("One of init parameters <= 0"); } t_long def_val = -1; rock->init (r_pvt, def_val); p_ref->init (r_pvt, def_val); equil->resize (EQUIL_TOTAL * r_eql); //!TODO: EQUIL_TOTAL instead of 3 pvto.resize (r_pvt); pvtdo.resize (r_pvt); pvtg.resize (r_pvt); pvtw.resize (r_pvt); swof.resize (r_sat); sgof.resize (r_sat); swfn.resize (r_sat); sgfn.resize (r_sat); sof2.resize (r_sat); sof3.resize (r_sat); }
bs_mesh_grdecl::bs_mesh_grdecl(const bs_mesh_grdecl& src) : bs_refcounter (src) { // TODO: BUG: bs_throw_exception ("NOT IMPL YET"); //*this = src; }
keyword_info_base::keyword_info_base(const keyword_info_base& src) : bs_refcounter (src), objbase (src) { // TODO: BUG: bs_throw_exception ("NOT IMPL YET"); //*this = src; }
// FIXME: void jacobian::restore_sec_solution () { if (secondary > 0) { if (phases != matrix->get_matrix ("flux")->get_n_block_size ()) { bs_throw_exception ("phases and flux block_size mismatch"); } spv_long rows = matrix->get_matrix ("flux")->get_rows_ptr (); t_float *sp_diag = sp_diagonal->data (); t_double *sol = solution->data (); t_double *sec_sol = sec_solution->data (); t_float *sec_rhs_ = sec_rhs->data (); // OPENMP for (t_long i = 0, cnt = (t_long)rows->size (); i < cnt - 1; ++i) { t_float *sp_block = &sp_diag[secondary * phases * i]; t_double *sol_block = &sol[phases * i]; sec_sol[i] = sec_rhs_[i]; VV_PROD_M (phases, sp_block, sol_block, sec_sol[i]); } } }
smesh_keywords::smesh_keywords(const smesh_keywords& src) : bs_refcounter (src), base_t (src) { // TODO: BUG: bs_throw_exception ("NOT IMPL YET"); //*this = src; }
void idata::set_density (spv_float density) { if ((density->size() % 3 != 0) || (density->size()<3)) { bs_throw_exception ("Not enough valid arguments yet"); } set_density_internal(&(*density)[0]); }
void mesh_base::check_data() const { #ifndef PURE_MESH if (n_elements <= 0) bs_throw_exception (boost::format ("n_elements = %d is out of range")% n_elements); if (n_active_elements <= 0) bs_throw_exception (boost::format ("n_active_elements = %d is out of range")% n_active_elements); // if (n_connections <= 0) // bs_throw_exception (boost::format ("n_connections = %d is out of range")% n_connections); if (!volumes->size ()) bs_throw_exception ("volumes array is not initialized"); if (!ext_to_int->size ()) bs_throw_exception ("ext_to_int array is not initialized"); #endif }
/** * @brief setup for CGS * * @param matrix -- input matrix * * @return 0 if success */ int gs_solver::setup (sp_matrix_t matrix) { if (!matrix) { bs_throw_exception ("gs: Passed matrix is null"); } return 0; }
void bs_stream::add_section (int section, int level) { if (sections_.find (section) != sections_.end ()) { bs_throw_exception ("Section already exists"); } sections_.insert (std::make_pair (section, level)); }
element_plane_orientation_t get_reverse_orientation (element_plane_orientation_t orient) { switch (orient) { case x_axis_plus: return x_axis_minus; case x_axis_minus: return x_axis_plus; case y_axis_plus: return y_axis_minus; case y_axis_minus: return y_axis_plus; case z_axis_plus: return z_axis_minus; case z_axis_minus: return z_axis_plus; default: bs_throw_exception ("Invalid orientation!"); } }
bs_channel::sp_stream_t bs_channel::get_stream (const std::string &name) const { for (size_t i = 0, cnt = output_streams_.size (); i < cnt; ++i) { if (output_streams_[i]->get_name () == name) { return output_streams_[i]; } } bs_throw_exception (boost::format ("Unknown stream name %s") % name); }
/** * @brief setup for CGS * * @param matrix -- input matrix * * @return 0 if success */ int cgs_solver::setup (sp_matrix_t matrix) { if (!matrix) { bs_throw_exception ("CGS: Passed matrix is null"); } BS_ASSERT (prop); if (prec) { return prec->setup (matrix); } return 0; }
// FIXME: in release symbol not found if inlined //inline void mesh_element3d::get_plane (element_plane_orientation_t orientation, plane_t &plane) const { switch (orientation) { case x_axis_minus: //left_cross plane[0] = corners[0]; plane[1] = corners[2]; plane[2] = corners[4]; plane[3] = corners[6]; break; case x_axis_plus: //right_cross plane[0] = corners[1]; plane[1] = corners[3]; plane[2] = corners[5]; plane[3] = corners[7]; break; case y_axis_minus: //top_cross plane[0] = corners[0]; plane[1] = corners[1]; plane[2] = corners[4]; plane[3] = corners[5]; break; case y_axis_plus: //bottom_cross plane[0] = corners[2]; plane[1] = corners[3]; plane[2] = corners[6]; plane[3] = corners[7]; break; case z_axis_minus: //lower_cross plane[0] = corners[0]; plane[1] = corners[2]; plane[2] = corners[1]; plane[3] = corners[3]; break; case z_axis_plus: //upper_cross plane[0] = corners[4]; plane[1] = corners[6]; plane[2] = corners[5]; plane[3] = corners[7]; break; default: bs_throw_exception ("Invalid orientation!");; } }
// FIXME: void jacobian::summ_rhs () { if (rhs->size () != rhs_flux->size ()) { bs_throw_exception ("rhs and rhs_flux size mismatch"); } t_float *rhs_ = rhs->data (); t_float *rhs_flux_ = rhs_flux->data (); // OPENMP: for (size_t i = 0, cnt = rhs->size (); i < cnt; ++i) { rhs_[i] += rhs_flux_[i]; } }
/** * \brief setup preconditioner (merge matrices if needed) * * \param matrix Various matrix * \return 0 if success */ int bcsr_ilu_prec::setup (sp_matrix_t matrix) { BS_ASSERT (matrix); t_long n; t_long nb; t_long b_sqr; bool ff = prop->get_b (use_internal_matrix); sp_bcsr_matrix_t ilu; if (dynamic_cast<bcsr_matrix_iface_t *> (matrix.lock ())) { ilu = matrix; BS_ASSERT (ilu); } if (ff) { if (!lu_matrix) { lu_matrix = BS_KERNEL.create_object (matrix->bs_resolve_type ()); if (!lu_matrix) { bs_throw_exception ("Can not create matrix"); } } if (lu_matrix->copy (ilu)) { bs_throw_exception ("Can not make matrix copy"); } n = lu_matrix->get_n_rows (); nb = lu_matrix->get_n_block_size (); } else { n = ilu->get_n_rows (); nb = ilu->get_n_block_size (); } spv_long sp_ilu_rows = ff ? lu_matrix->get_rows_ptr () : ilu->get_rows_ptr (); spv_long sp_ilu_cols = ff ? lu_matrix->get_cols_ind () : ilu->get_cols_ind (); spv_float sp_ilu_values = ff ? lu_matrix->get_values () : ilu->get_values (); t_long *ilu_rows = &(*sp_ilu_rows)[0]; t_long *ilu_cols = &(*sp_ilu_cols)[0]; t_float *ilu_values = &(*sp_ilu_values)[0]; b_sqr = nb * nb; // common //int r_code = 0; t_long i, j, j1, j2, j3, cl, k; t_float *block; //ilu.ascii_write_in_csr_format ("ilu_set_internal"); // ilu.write_matrix_to_file ("matrix.out"); // ---------------------- // STAGE 3: build ilu factorization t_long i_str; //fp_type *d_block, *dd_block; t_float *d_block, *dd_block; t_double d; t_long jj, jj1, jj2; // loop through all rows for (i = 0; i < n; ++i) { // update i-th row by 0..i-1 row j1 = ilu_rows[i]; j2 = j1;//ilu_diag_ind[i]; j3 = ilu_rows[i + 1]; BS_ASSERT (j1 == j2) (j1) (j2); // for all nonzero elements in i-th string (in L part) // update it by diagonal element and update all other nonzero elements // in i-th string for (j = j1 + 1; j < j3; ++j) { // find corresponding diagonal element i_str = ilu_cols[j]; if (i_str < i) { // update by diagonal element block = &ilu_values[j * b_sqr]; d_block = &ilu_values[ilu_rows[i_str]/*ilu_diag_ind[i_str]*/ * b_sqr]; //BS_ASSERT (ilu_diag_ind[i_str] == ilu_rows[i_str]) (ilu_diag_ind[i_str]) (ilu_rows[i_str]); uLU_SEEK_L (nb, d_block, block, d); jj1 = ilu_rows[i_str]; jj2 = ilu_rows[i_str + 1]; k = j + 1; for (jj = jj1; jj < jj2; ++jj) { cl = ilu_cols[jj]; if (cl <= i_str) continue; if (ilu_cols[j1] == cl) { // upgrade by corresponding element d_block = &ilu_values[jj * b_sqr]; dd_block = &ilu_values[j1 * b_sqr]; LU_UPGRADE(nb, block, d_block, dd_block); } for (; k < j3 && ilu_cols[k] < cl; ++k) ; if (k < j3 && ilu_cols[k] == cl) { // upgrade by corresponding element d_block = &ilu_values[jj * b_sqr]; dd_block = &ilu_values[k * b_sqr]; LU_UPGRADE(nb, block, d_block, dd_block); } else if (k >= j3) break; } } else break; } // factorize i-th string block = &ilu_values[j2 * b_sqr]; uLU (nb, block, d); for (j = j1; j < j3; ++j) { t_long cl = ilu_cols[j]; if (cl > i) { d_block = &ilu_values[j * b_sqr]; uLU_SEEK_U (nb, block, d_block); } } } // ---------------------- return 0; }
int tfqmr_solver::solve (sp_matrix_t matrix, spv_double sp_rhs, spv_double sp_sol) { BOSOUT (section::solvers, level::debug) << "TFQMR\n" << bs_end; BS_ERROR (matrix, "tfqmr_solve"); BS_ERROR (sp_rhs->size (), "tfqmr_solve"); BS_ERROR (sp_sol->size (), "tfqmr_solve"); BS_ERROR (prop, "tfqmr_solve"); t_double rho_1, rho_2 = 1, alpha = 1, beta, sigma; int iter; const double epsmac = 1e-24; t_double r_norm, b_norm, den_norm, w_norm, eta, nu, tau, c; //fp_type *x = solution; //OMP_TIME_MEASURE_START (tfqmr_solve_timer); t_double *rhs = &(*sp_rhs)[0]; t_double *sol = &(*sp_sol)[0]; t_double tol = prop->get_f (tol_idx); tol *= tol; //resid = prop->get_residuals (); //convergence_rate = prop->get_convergence_rate (); int max_iter = prop->get_i (max_iters_idx); t_long n = matrix->get_n_rows () * matrix->get_n_block_size (); sp_p->resize (n); sp_v->resize (n); sp_w->resize (n); sp_u->resize (n); sp_q->resize (n); sp_d->resize (n); sp_res->resize (n); sp_r->resize (n); sp_rtilde->resize (n); sp_tmp->resize (n); sp_rhat->resize (n); sp_y->resize (n); //x_cgs = y + n; prop->set_b (success_idx, false); // solution = {0} sp_sol->assign (0); // r = {0} sp_r->assign (0); // TODO:paste sp_tmp->assign (0); sp_p->assign (0); sp_v->assign (0); sp_q->assign (0); sp_d->assign (0); t_double *r = &(*sp_r)[0]; t_double *p = &(*sp_p)[0]; t_double *v = &(*sp_v)[0]; t_double *w = &(*sp_w)[0]; t_double *u = &(*sp_u)[0]; t_double *q = &(*sp_q)[0]; t_double *d = &(*sp_d)[0]; t_double *res = &(*sp_res)[0]; t_double *rtilde = &(*sp_rtilde)[0]; t_double *tmp = &(*sp_tmp)[0]; t_double *rhat = &(*sp_rhat)[0]; t_double *y = &(*sp_y)[0]; // r = Ax0 - b matrix->calc_lin_comb (-1.0, 1.0, sp_sol, sp_rhs, sp_r); memcpy (rtilde, r, sizeof (t_double) * n); //rtilde.assign (r.begin (), r.end ()); // p0 = u0 = r0; //memcpy (p, r, n * sizeof (double)); memcpy (u, r, sizeof (t_double) * n); memcpy (p, r, sizeof (t_double) * n); memcpy (w, r, sizeof (t_double) * n); //u.assign (r.begin (), r.end ()); //p.assign (r.begin (), r.end ()); //w.assign (r.begin (), r.end ()); // tmp = M^(-1) * u; if (prec) { if (prec->solve_prec (matrix, sp_u, sp_tmp)) { bs_throw_exception ("TFQMR: Preconditioner failed"); } memcpy (u, tmp, sizeof (t_double) * n); memcpy (p, tmp, sizeof (t_double) * n); //u.assign (tmp.begin (), tmp.end ()); //p.assign (u.begin (), u.end ()); } matrix->matrix_vector_product (sp_p, sp_v); //tools::save_seq_vector (tools::string_formater ("1_well_bhp.%s.txt", it->first).str).save (it->second); r_norm = mv_vector_inner_product_n (r, r, n); if (r_norm <= tol) // initial guess quite good return 0; tau = sqrt (r_norm); rho_1 = r_norm; rho_2 = r_norm; b_norm = sqrt (mv_vector_inner_product_n (rhs, rhs, n)); if (b_norm > epsmac) // choose convergence criterion { // |r_i|/|b| <= eps if |b| > 0 tol *= b_norm; den_norm = b_norm; } else // (r_norm > epsmac) { // |r_i|/|r0| <= eps if |b| = 0 tol *= r_norm; den_norm = r_norm; } // set up initial norm and convergense factor //prop->set_relative_factor (den_norm); int m, count; // main loop for (iter = 0; iter < max_iter; ++iter) { //printf ("TFQMR iteration: %d, resid = %le\n", iter, r_norm); //fflush (stdout); // TODO: paste if (iter) { //rho_1 = mv_vector_inner_product (r, rtilde, n);//in first iter equals to r_norm if (rho_1 == 0) // failure { if (den_norm > epsmac) prop->set_f (final_res_idx, r_norm / den_norm); else prop->set_f (final_res_idx, r_norm); bs_throw_exception ("TFQMR: Failure - rho_1 == 0"); } sum_vector_n (u, (t_double)1., res, beta, p, n); //p[n] = u[n]+beta*res //v.assign (n, 0); memset (v, 0, sizeof (t_double) * n); matrix->matrix_vector_product (sp_p, sp_v); //v[n]=Ap[n] } sigma = mv_vector_inner_product_n (rtilde, v, n); //sigma=(rtilde,v[n-1]) alpha = rho_1/sigma; // tmp = M^(-1)*v if (prec) { if (prec->solve_prec (matrix, sp_v, sp_tmp)) { bs_throw_exception ("TFQMR: Preconditioner failed"); } memcpy (v, tmp, sizeof (t_double) * n); //v.assign (tmp.begin (), tmp.end ()); } sum_vector_n (u, (t_double)1., v, -alpha, q, n); //q[n] = u[n-1]-alpha*v[n-1] sum_vector_n (u, (t_double)1., q, (t_double)1., res, n); //res = u[n-1]+q[n] //tmp.assign (n, 0); memset (tmp, 0, sizeof (t_double) * n); matrix->matrix_vector_product (sp_res, sp_tmp);// tmp=A*res sum_vector_n (r, (t_double)1., tmp, -alpha, r, n);// r=r-alpha*res //r_norm_old = r_norm; r_norm = mv_vector_inner_product_n (r, r, n); for (m = 1; m <= 2 ; m++) { if (m == 1) // m is odd { memcpy (y, u, sizeof (t_double) * n); //y.assign (u.begin (), u.end ()); w_norm = sqrt(r_norm * r_norm); } else // m is even { memcpy (y, q, sizeof (t_double) * n); //y.assign (q.begin (), q.end ()); w_norm = sqrt(r_norm); } sum_vector_n (y, (t_double)1., d, eta*nu*nu/alpha, d, n); //d[m] = y[m] + (eta[m-1]*nu[m-1]^2/alpha[n-1])*d[m-1] nu = w_norm/tau; //nu[m]=||w[m+1]||/tau[m-1] c = 1./sqrt (1. + nu*nu); tau = tau*c*nu; //tau[m]=tau[m-1]nu[m]c[m] eta = c*c*alpha; //eta[m]=c[m]^2*alpha[n-1] //SUM_VECTOR(x,d,1,alpha,x_cgs,k,n); //x_cgs[n] = x[2n-1]+alpha[n-1]*d[2n] sum_vector_n (sol, (t_double)1., d, eta, sol, n); //x[m] = x[m-1]+eta[m]*d[m] if (r_norm <= tol) { count = 1; break; } } if (r_norm <= tol) break; rho_1 = mv_vector_inner_product_n (r, rtilde, n);//in first iter equals to r_norm beta = rho_1 / rho_2; // rhat = M^(-1) * r; if (prec) { if (prec->solve_prec (matrix, sp_r, sp_rhat)) { bs_throw_exception ("TFQMR: Preconditioner failed"); } } else // no precondition (preconditioner=identity_matrix) { memcpy (rhat, r, sizeof (t_double) * n); //rhat.assign (r.begin (), r.end ()); } sum_vector_n (rhat, (t_double)1., q, beta, u, n); //u[n] = r[n]+beta*q[n] sum_vector_n (q, (t_double)1., p, beta, res, n); //res = q[n]+beta*p[n-1] rho_2 = rho_1; } //TODO: end prop->set_i (iters_idx, iter + 1); prop->set_b (success_idx, true); /* //additional checking convergence mv_calc_lin_comb (matrix, -1.0, 1.0, solution, rhs, r); r_norm = mv_vector_inner_product (r, r, n); */ if (den_norm > epsmac) prop->set_f (final_res_idx, r_norm / den_norm); else prop->set_f (final_res_idx, r_norm); //printf ("TFQMR OK! iters = %d, resid = %le\n", lprop->iters, lprop->final_resid); //OMP_TIME_MEASURE_END (tfqmr_solve_timer); return 0; }
int cgs_solver::solve (sp_matrix_t matrix, spv_double sp_rhs, spv_double sp_sol) { #ifdef _DEBUG BOSOUT (section::solvers, level::debug) << "CGS\n" << bs_end; #endif BS_ERROR (sp_rhs->size (), "cgs_solve"); BS_ERROR (sp_sol->size (), "cgs_solve"); BS_ERROR (prop, "cgs_solve"); t_double rho_1, rho_2 = 1, alpha = 1, beta, sigma; int iter; const double epsmac = 1e-24; t_double r_norm, b_norm, den_norm; //fp_type *x = solution; t_double *rhs = &(*sp_rhs)[0]; t_double *sol = &(*sp_sol)[0]; const t_double one = 1.0; //OMP_TIME_MEASURE_START (cgs_solve_timer); t_double tol = prop->get_f (tol_idx); tol *= tol; //resid = prop->get_residuals (); //convergence_rate = prop->get_convergence_rate (); int max_iter = prop->get_i (max_iters_idx); t_long n = matrix->get_n_rows () * matrix->get_n_block_size (); BS_ASSERT (n == (t_long)sp_sol->size ()); t_double *p = &(*sp_p)[0]; t_double *phat = &(*sp_phat)[0]; t_double *v = &(*sp_v)[0]; t_double *tmp = &(*sp_tmp)[0]; t_double *q = &(*sp_q)[0]; t_double *u = &(*sp_u)[0]; t_double *d = &(*sp_d)[0]; t_double *dhat = &(*sp_dhat)[0]; t_double *r = &(*sp_r)[0]; t_double *rtilde = &(*sp_rtilde)[0]; //t_double *r_old = &(*sp_r_old)[0]; prop->set_b (success_idx, false); // solution = {0} //assign (solution, n, 0); memset (sol, 0, sizeof (t_double) * n); //solution.assign (n, 0); sp_p->resize (n); sp_phat->resize (n); sp_v->resize (n); sp_tmp->resize (n); sp_q->resize (n); sp_u->resize (n); sp_d->resize (n); sp_dhat->resize (n); sp_r->resize (n); sp_rtilde->resize (n); sp_r_old->resize (n); // r = {0} //r.assign (n, 0); memset (r, 0, sizeof (t_double) * n); memset (tmp, 0, sizeof (t_double) * n); memset (p, 0, sizeof (t_double) * n); memset (v, 0, sizeof (t_double) * n); memset (q, 0, sizeof (t_double) * n); // TODO:paste //tmp.assign (n, 0); //p.assign (n, 0); //v.assign (n, 0); //q.assign (n, 0); // p0 = u0 = r0; //u.assign (r.begin (), r.end ()); memcpy (u, r, sizeof (t_double) * n); // TODO:end // r = Ax0 - b matrix->calc_lin_comb (-1.0, 1.0, sp_sol, sp_rhs, sp_r); //rtilde.assign (r.begin (), r.end ()); memcpy (rtilde, r, sizeof (t_double) * n); //tools::save_seq_vector (tools::string_formater ("1_well_bhp.%s.txt", it->first).str).save (it->second); r_norm = mv_vector_inner_product_n (r, r, n); if (r_norm <= tol) // initial guess quite good return 0; rho_1 = r_norm; b_norm = sqrt (mv_vector_inner_product_n (rhs, rhs, n)); // TODO:delete //p.assign (r.begin (), r.end ()); //rtilde.assign (r.begin (), r.end ()); //v.assign (n, 0); // TODO:end if (b_norm > epsmac) // choose convergence criterion { // |r_i|/|b| <= eps if |b| > 0 tol *= b_norm; den_norm = b_norm; } else // (r_norm > epsmac) { // |r_i|/|r0| <= eps if |b| = 0 tol *= r_norm; den_norm = r_norm; } // set up initial norm and convergense factor //prop->set_relative_factor (den_norm); // main loop for (iter = 0; iter < max_iter; ++iter) { //printf ("CGS iteration: %d, resid = %le\n", iter, r_norm); //fflush (stdout); // TODO: paste if (iter) { //rho_1 = (r,rtilde) rho_1 = mv_vector_inner_product_n (r, rtilde, n); //in first iter equals to r_norm if (rho_1 == 0) // failure { if (den_norm > epsmac) prop->set_f (final_res_idx, r_norm / den_norm); else prop->set_f (final_res_idx, r_norm); bs_throw_exception ("CGS: Failure - rho_1 == 0"); } } beta = rho_1/rho_2; // beta = rho_n/rho_n-1 rho_2 = rho_1; // u = r + beta*q sum_vector_n (r, one, q, beta, u, n); // tmp = q+beta*p_old sum_vector_n (q, one, p, beta, tmp, n); // p_new = u + beta*tmp sum_vector_n (u, one, tmp, beta, p, n); //temp_p.assign (p.begin (), p.end ()); if (prec) { if (prec->solve_prec (matrix, sp_p, sp_phat)) { bs_throw_exception ("CGS: Preconditioner failed"); } } else // no precondition (preconditioner=identity_matrix) { memcpy (phat, p, sizeof (t_double) * n); //phat.assign (p.begin (), p.end ()); } // v = A * phat = A * p, if no precondition; //v.assign (n, 0); memset (v, 0, sizeof (t_double) * n); matrix->matrix_vector_product (sp_phat, sp_v); // sigma = (v,rtilde) sigma = mv_vector_inner_product_n (rtilde, v, n); if (sigma > epsmac || sigma < -epsmac) // alpha = rho_1/sigma alpha = rho_1 / sigma; else // failure { if (den_norm > epsmac) prop->set_f (final_res_idx, r_norm / den_norm); else prop->set_f (final_res_idx, r_norm); bs_throw_exception ("CGS: Failure - sigma == 0"); } // q = u - alpha*v sum_vector_n (u, one, v, -alpha, q, n); // d = u + q sum_vector_n (u, one, q, one, d, n); // dhat = M^(-1) * d; //temp_d.assign (d.begin (), d.end ()); if (prec) { if(prec->solve_prec (matrix, sp_d, sp_dhat)) { bs_throw_exception ("CGS: Preconditioner failed"); } } else // no precondition (preconditioner=identity_matrix) { //dhat.assign (d.begin (), d.end ()); memcpy (dhat, d, sizeof (t_double) * n); } //tmp.assign (n, 0); memset (tmp, 0, sizeof (t_double) * n); // tmp = A*d matrix->matrix_vector_product (sp_dhat, sp_tmp); // r = r - alpha*tmp sum_vector_n (r, one, tmp, -alpha, r, n); // x = x + alpha*dhat sum_vector_n (sol, one, dhat, alpha, sol, n); r_norm = mv_vector_inner_product_n (r, r, n); if (r_norm <= tol) // && check_resid_for_matbalance (n_rows, nb, r, matb_tol)) break; } //tools::save_seq_vector ("solution.txt").save(solution); //TODO: end prop->set_i (iters_idx, iter + 1); prop->set_b (success_idx, true); /* //additional checking convergence mv_calc_lin_comb (matrix, -1.0, 1.0, solution, rhs, r); r_norm = mv_vector_inner_product (r, r, n); */ if (den_norm > epsmac) prop->set_f (final_res_idx, r_norm / den_norm); else prop->set_f (final_res_idx, r_norm); //printf ("CGS OK! iters = %d, resid = %le\n", lprop->iters, lprop->final_resid); //OMP_TIME_MEASURE_END (bicgstab_solve_timer); return 0; }