103 if (a_its < 0) { a_its = m_maxiter; }
108 V r = m_linop->makeVecRHS();
109 V rh = m_linop->makeVecRHS();
110 V p = m_linop->makeVecRHS();
111 V ph = m_linop->makeVecLHS();
112 V v = m_linop->makeVecRHS();
113 V sh = m_linop->makeVecLHS();
114 V t = m_linop->makeVecRHS();
116 if (m_nonzero_guess) {
118 m_linop->assign(ph, a_sol);
119 m_linop->apply(v, ph);
120 m_linop->linComb(r,
RT(1), a_rhs,
RT(-1), v);
122 m_linop->setToZero(a_sol);
123 m_linop->assign(r, a_rhs);
125 m_linop->assign(rh, r);
127 RT rnorm = m_linop->norm2(r);
128 RT const rnorm0 = rnorm;
133 amrex::Print() <<
"BiCGStab: Initial residual (error0) = " << rnorm0 <<
'\n';
136 if (rnorm0 ==
RT(0) || rnorm0 < m_atol) {
141 RT rho_1 =
RT(0), alpha =
RT(0), omega =
RT(0);
143 auto converged = [&] (
RT rn) {
144 return rn ==
RT(0) || rn < m_rtol*rnorm0 || rn < m_atol;
147 for (
int iter = 1; iter <= a_its; ++iter)
149 RT const rho = m_linop->dotProduct(rh, r);
150 if (rho ==
RT(0) || !amrex::isfinite(rho)) { m_status = 2;
break; }
153 m_linop->assign(p, r);
155 RT const beta = (rho/rho_1)*(alpha/omega);
156 m_linop->increment(p, v, -omega);
157 m_linop->scale(p,
beta);
158 m_linop->increment(p, r,
RT(1));
161 m_linop->precond(ph, p);
162 m_linop->apply(v, ph);
164 RT const rhv = m_linop->dotProduct(rh, v);
165 if (rhv ==
RT(0) || !amrex::isfinite(rhv)) { m_status = 3;
break; }
168 m_linop->increment(a_sol, ph, alpha);
169 m_linop->increment(r, v, -alpha);
171 rnorm = m_linop->norm2(r);
176 amrex::Print() <<
"BiCGStab: Half Iter " << std::setw(11) << iter
177 <<
" rel. err. " << rnorm/rnorm0 <<
'\n';
180 if (converged(rnorm)) { m_status = 0;
break; }
182 m_linop->precond(sh, r);
183 m_linop->apply(t, sh);
185 RT const tt = m_linop->dotProduct(t, t);
186 if (tt ==
RT(0) || !amrex::isfinite(tt)) { m_status = 4;
break; }
187 omega = m_linop->dotProduct(t, r) / tt;
188 if (omega ==
RT(0) || !amrex::isfinite(omega)) { m_status = 5;
break; }
190 m_linop->increment(a_sol, sh, omega);
191 m_linop->increment(r, t, -omega);
193 rnorm = m_linop->norm2(r);
197 amrex::Print() <<
"BiCGStab: Iteration " << std::setw(11) << iter
198 <<
" rel. err. " << rnorm/rnorm0 <<
'\n';
201 if (converged(rnorm)) { m_status = 0;
break; }
206 if (m_status == -1) { m_status = 1; }
209 amrex::Print() <<
"BiCGStab: Final: Iteration " << std::setw(4) << m_its
210 <<
" rel. err. " << rnorm/rnorm0 <<
'\n';
213 if (m_status != 0 && m_verbose > 0) {
214 amrex::Print() <<
"BiCGStab: Failed to converge, status = " << m_status <<
'\n';
void solve(V &a_sol, V const &a_rhs, RT a_tol_rel, RT a_tol_abs, int a_its=-1)
Solve the linear system.
Definition AMReX_BiCGStab.H:95