void CR<OperatorType, VectorType, ValueType>::SolvePrecond_(const VectorType &rhs, VectorType *x) { LOG_DEBUG(this, "CR::SolvePrecond_()", " #*# begin"); assert(x != NULL); assert(x != &rhs); assert(this->op_ != NULL); assert(this->precond_ != NULL); assert(this->build_ == true); const OperatorType *op = this->op_; VectorType *r = &this->r_; VectorType *z = &this->z_; VectorType *p = &this->p_; VectorType *q = &this->q_; VectorType *v = &this->v_; VectorType *t = &this->t_; ValueType alpha, beta; ValueType rho, rho_old; // initial residual = b - Ax op->Apply(*x, z); z->ScaleAdd(ValueType(-1.0), rhs); // Solve Mr=z this->precond_->SolveZeroSol(*z, r); // p = r p->CopyFrom(*r); // t = z t->CopyFrom(*z); // use for |b-Ax0| ValueType res_norm = this->Norm(*t); if (this->iter_ctrl_.InitResidual(paralution_abs(res_norm)) == false) { LOG_DEBUG(this, "CR::SolvePrecond_()", " #*# end"); return; } // use for |b| // this->iter_ctrl_.InitResidual(rhs.Norm()); // v=Ar op->Apply(*r, v); // rho = (r,v) rho = r->DotNonConj(*v); // q=Ap op->Apply(*p, q); // Mz=q this->precond_->SolveZeroSol(*q, z); // alpha = rho / (q,z) alpha = rho / q->DotNonConj(*z); // x = x + alpha * p x->AddScale(*p, alpha); // r = r - alpha * z r->AddScale(*z, ValueType(-1.0)*alpha); // t = t - alpha * q t->AddScale(*q, ValueType(-1.0)*alpha); res_norm = this->Norm(*t); while (!this->iter_ctrl_.CheckResidual(paralution_abs(res_norm), this->index_)) { rho_old = rho; // v=Ar op->Apply(*r, v); // rho = (r,v) rho = r->DotNonConj(*v); beta = rho / rho_old; // p = beta*p + r p->ScaleAdd(beta, *r); // q = beta*q + v q->ScaleAdd(beta, *v); // Mz=q this->precond_->SolveZeroSol(*q, z); // alpha = rho / (q,z) alpha = rho / q->DotNonConj(*z); // x = x + alpha * p x->AddScale(*p, alpha); // r = r - alpha * z r->AddScale(*z, ValueType(-1.0)*alpha); // t = t - alpha * q t->AddScale(*q, ValueType(-1.0)*alpha); res_norm = this->Norm(*t); } LOG_DEBUG(this, "CR::SolvePrecond_()", " #*# end"); }